From fe333d2ec8051a628e6e18ed658b368f275defa4 Mon Sep 17 00:00:00 2001 From: Alex Tugarev Date: Mon, 13 Nov 2023 12:32:24 +0000 Subject: [PATCH] WIP --- .../dashboard/src/components/AuthorizeGit.tsx | 15 +- .../src/components/RepositoryFinder.tsx | 10 +- .../auth-providers/auth-provider-query.ts | 11 -- .../dashboard/src/projects/NewProject.tsx | 38 ++-- .../new-project/NewProjectAuthRequired.tsx | 10 +- .../new-project/NewProjectRepoSelection.tsx | 7 +- components/dashboard/src/provider-utils.tsx | 15 ++ .../src/user-settings/AuthEntryItem.tsx | 16 +- .../src/user-settings/Integrations.tsx | 172 +++++++++--------- .../src/workspaces/CreateWorkspacePage.tsx | 12 +- 10 files changed, 158 insertions(+), 148 deletions(-) diff --git a/components/dashboard/src/components/AuthorizeGit.tsx b/components/dashboard/src/components/AuthorizeGit.tsx index 96e945b1aa8cd9..cbb239fc7cf86b 100644 --- a/components/dashboard/src/components/AuthorizeGit.tsx +++ b/components/dashboard/src/components/AuthorizeGit.tsx @@ -4,10 +4,9 @@ * See License.AGPL.txt in the project root for license information. */ -import { AuthProviderInfo } from "@gitpod/gitpod-protocol"; import { FC, useCallback, useContext } from "react"; import { Link } from "react-router-dom"; -import { useAuthProviders } from "../data/auth-providers/auth-provider-query"; +import { useAuthProviderDescriptions } from "../data/auth-providers/auth-provider-query"; import { openAuthorizeWindow } from "../provider-utils"; import { getGitpodService } from "../service/service"; import { UserContext, useCurrentUser } from "../user-context"; @@ -16,29 +15,29 @@ import { Heading2, Heading3, Subheading } from "./typography/headings"; import classNames from "classnames"; import { iconForAuthProvider, simplifyProviderName } from "../provider-utils"; import { useIsOwner } from "../data/organizations/members-query"; +import { AuthProviderDescription } from "@gitpod/public-api/lib/gitpod/v1/authprovider_pb"; export function useNeedsGitAuthorization() { - const authProviders = useAuthProviders(); + const authProviders = useAuthProviderDescriptions(); const user = useCurrentUser(); if (!user || !authProviders.data) { return false; } - return !authProviders.data.some((ap) => user.identities.some((i) => ap.authProviderId === i.authProviderId)); + return !authProviders.data.some((ap) => user.identities.some((i) => ap.id === i.authProviderId)); } export const AuthorizeGit: FC<{ className?: string }> = ({ className }) => { const { setUser } = useContext(UserContext); const owner = useIsOwner(); - const authProviders = useAuthProviders(); + const authProviders = useAuthProviderDescriptions(); const updateUser = useCallback(() => { getGitpodService().server.getLoggedInUser().then(setUser); }, [setUser]); const connect = useCallback( - (ap: AuthProviderInfo) => { + (ap: AuthProviderDescription) => { openAuthorizeWindow({ host: ap.host, - scopes: ap.requirements?.default, overrideScopes: true, onSuccess: updateUser, }); @@ -91,7 +90,7 @@ export const AuthorizeGit: FC<{ className?: string }> = ({ className }) => { className="mt-3 btn-login flex-none w-56 px-0 py-0.5 inline-flex" >
- {iconForAuthProvider(ap.authProviderType)} + {iconForAuthProvider(ap.type)} Continue with {simplifyProviderName(ap.host)} diff --git a/components/dashboard/src/components/RepositoryFinder.tsx b/components/dashboard/src/components/RepositoryFinder.tsx index 3f185b8e527f2c..309b9ec625c77d 100644 --- a/components/dashboard/src/components/RepositoryFinder.tsx +++ b/components/dashboard/src/components/RepositoryFinder.tsx @@ -11,8 +11,9 @@ import { ReactComponent as RepositoryIcon } from "../icons/RepositoryWithColor.s import { SuggestedRepository } from "@gitpod/gitpod-protocol"; import { MiddleDot } from "./typography/MiddleDot"; import { useUnifiedRepositorySearch } from "../data/git-providers/unified-repositories-search-query"; -import { useAuthProviders } from "../data/auth-providers/auth-provider-query"; +import { useAuthProviderDescriptions } from "../data/auth-providers/auth-provider-query"; import { ReactComponent as Exclamation2 } from "../images/exclamation2.svg"; +import { AuthProviderType } from "@gitpod/public-api/lib/gitpod/v1/authprovider_pb"; interface RepositoryFinderProps { selectedContextURL?: string; @@ -39,7 +40,7 @@ export default function RepositoryFinder({ hasMore, } = useUnifiedRepositorySearch({ searchString, excludeProjects }); - const authProviders = useAuthProviders(); + const authProviders = useAuthProviderDescriptions(); const handleSelectionChange = useCallback( (selectedID: string) => { @@ -115,7 +116,10 @@ export default function RepositoryFinder({ isSelectable: false, } as ComboboxElement); } - if (searchString.length >= 3 && authProviders.data?.some((p) => p.authProviderType === "BitbucketServer")) { + if ( + searchString.length >= 3 && + authProviders.data?.some((p) => p.type === AuthProviderType.BITBUCKET_SERVER) + ) { // add an element that tells the user that the Bitbucket Server does only support prefix search result.push({ id: "bitbucket-server", diff --git a/components/dashboard/src/data/auth-providers/auth-provider-query.ts b/components/dashboard/src/data/auth-providers/auth-provider-query.ts index eba3cc9741f354..d4bafde79e4d45 100644 --- a/components/dashboard/src/data/auth-providers/auth-provider-query.ts +++ b/components/dashboard/src/data/auth-providers/auth-provider-query.ts @@ -4,9 +4,7 @@ * See License.AGPL.txt in the project root for license information. */ -import { AuthProviderInfo } from "@gitpod/gitpod-protocol"; import { useQuery } from "@tanstack/react-query"; -import { getGitpodService } from "../../service/service"; import { authProviderClient } from "../../service/public-api"; import { useCurrentUser } from "../../user-context"; import { @@ -14,15 +12,6 @@ import { ListAuthProviderDescriptionsRequest, } from "@gitpod/public-api/lib/gitpod/v1/authprovider_pb"; -export const useAuthProviders = () => { - return useQuery({ - queryKey: ["auth-providers"], - queryFn: async () => { - return await getGitpodService().server.getAuthProviders(); - }, - }); -}; - export const useAuthProviderDescriptions = () => { const user = useCurrentUser(); const query = useQuery({ diff --git a/components/dashboard/src/projects/NewProject.tsx b/components/dashboard/src/projects/NewProject.tsx index 315f4b33da6e6c..905894d60ce89d 100644 --- a/components/dashboard/src/projects/NewProject.tsx +++ b/components/dashboard/src/projects/NewProject.tsx @@ -4,7 +4,7 @@ * See License.AGPL.txt in the project root for license information. */ -import { AuthProviderInfo, Project } from "@gitpod/gitpod-protocol"; +import { Project } from "@gitpod/gitpod-protocol"; import { FC, useCallback, useContext, useEffect, useMemo, useState } from "react"; import ErrorMessage from "../components/ErrorMessage"; import { useCurrentOrg } from "../data/organizations/orgs-query"; @@ -13,19 +13,20 @@ import { iconForAuthProvider, openAuthorizeWindow, simplifyProviderName } from " import { getGitpodService } from "../service/service"; import { UserContext, useCurrentUser } from "../user-context"; import { Heading1, Subheading } from "../components/typography/headings"; -import { useAuthProviders } from "../data/auth-providers/auth-provider-query"; +import { useAuthProviderDescriptions } from "../data/auth-providers/auth-provider-query"; import { AuthorizeGit, useNeedsGitAuthorization } from "../components/AuthorizeGit"; import { NewProjectRepoSelection } from "./new-project/NewProjectRepoSelection"; import { NewProjectSubheading } from "./new-project/NewProjectSubheading"; import { Button } from "../components/Button"; +import { AuthProviderDescription, AuthProviderType } from "@gitpod/public-api/lib/gitpod/v1/authprovider_pb"; export default function NewProject() { const currentTeam = useCurrentOrg()?.data; const user = useCurrentUser(); - const authProviders = useAuthProviders(); + const authProviders = useAuthProviderDescriptions(); // State this component manages - const [selectedProvider, setSelectedProvider] = useState(); + const [selectedProvider, setSelectedProvider] = useState(); const [project, setProject] = useState(); // Defaults selectedProviderHost if not set yet @@ -34,9 +35,7 @@ export default function NewProject() { for (let i = user.identities.length - 1; i >= 0; i--) { const candidate = user.identities[i]; if (candidate) { - const authProvider = authProviders.data.find( - (ap) => ap.authProviderId === candidate.authProviderId, - ); + const authProvider = authProviders.data.find((ap) => ap.id === candidate.authProviderId); if (authProvider) { setSelectedProvider(authProvider); break; @@ -107,8 +106,8 @@ export default function NewProject() { } type NewProjectMainContentProps = { - selectedProvider?: AuthProviderInfo; - onProviderSelected: (ap: AuthProviderInfo, updateUser?: boolean) => void; + selectedProvider?: AuthProviderDescription; + onProviderSelected: (ap: AuthProviderDescription, updateUser?: boolean) => void; onProjectCreated: (project: Project) => void; }; const NewProjectMainContent: FC = ({ @@ -117,12 +116,12 @@ const NewProjectMainContent: FC = ({ onProjectCreated, }) => { const { setUser } = useContext(UserContext); - const authProviders = useAuthProviders(); + const authProviders = useAuthProviderDescriptions(); const needsGitAuth = useNeedsGitAuthorization(); const [showGitProviders, setShowGitProviders] = useState(false); const onGitProviderSeleted = useCallback( - async (ap: AuthProviderInfo, updateUser?: boolean) => { + async (ap: AuthProviderDescription, updateUser?: boolean) => { // TODO: Can we push this down into where sends updateUser=true? if (updateUser) { setUser(await getGitpodService().server.getLoggedInUser()); @@ -151,23 +150,22 @@ const NewProjectMainContent: FC = ({ }; const GitProviders: FC<{ - authProviders: AuthProviderInfo[]; - onProviderSelected: (ap: AuthProviderInfo, updateUser?: boolean) => void; + authProviders: AuthProviderDescription[]; + onProviderSelected: (ap: AuthProviderDescription, updateUser?: boolean) => void; }> = ({ authProviders, onProviderSelected }) => { const [errorMessage, setErrorMessage] = useState(undefined); const selectProvider = useCallback( - async (ap: AuthProviderInfo) => { + async (ap: AuthProviderDescription) => { setErrorMessage(undefined); const token = await getGitpodService().server.getToken({ host: ap.host }); - if (token && !(ap.authProviderType === "GitHub" && !token.scopes.includes("repo"))) { + if (token && !(ap.type === AuthProviderType.GITHUB && !token.scopes.includes("repo"))) { onProviderSelected(ap); return; } await openAuthorizeWindow({ host: ap.host, - scopes: ap.authProviderType === "GitHub" ? ["repo"] : ap.requirements?.default, onSuccess: async () => { onProviderSelected(ap, true); }, @@ -194,10 +192,10 @@ const GitProviders: FC<{ () => authProviders.filter( (p) => - p.authProviderType === "GitHub" || + p.type === AuthProviderType.GITHUB || p.host === "bitbucket.org" || - p.authProviderType === "GitLab" || - p.authProviderType === "BitbucketServer", + p.type === AuthProviderType.GITLAB || + p.type === AuthProviderType.BITBUCKET_SERVER, ), [authProviders], ); @@ -216,7 +214,7 @@ const GitProviders: FC<{ className="btn-login flex-none w-56 h-10 p-0 inline-flex" onClick={() => selectProvider(ap)} > - {iconForAuthProvider(ap.authProviderType)} + {iconForAuthProvider(ap.type)} Continue with {simplifyProviderName(ap.host)} diff --git a/components/dashboard/src/projects/new-project/NewProjectAuthRequired.tsx b/components/dashboard/src/projects/new-project/NewProjectAuthRequired.tsx index aef5370d501f7a..cb2da4446427b9 100644 --- a/components/dashboard/src/projects/new-project/NewProjectAuthRequired.tsx +++ b/components/dashboard/src/projects/new-project/NewProjectAuthRequired.tsx @@ -5,7 +5,7 @@ */ import { FC, useCallback } from "react"; -import { useAuthProviders } from "../../data/auth-providers/auth-provider-query"; +import { useAuthProviderDescriptions } from "../../data/auth-providers/auth-provider-query"; import { openAuthorizeWindow } from "../../provider-utils"; type Props = { @@ -18,7 +18,7 @@ export const NewProjectAuthRequired: FC = ({ areGitHubWebhooksUnauthorized = false, onReconfigure, }) => { - const authProviders = useAuthProviders(); + const authProviders = useAuthProviderDescriptions(); const handleAuthorize = useCallback(() => { const ap = authProviders.data?.find((ap) => ap.host === selectedProviderHost); @@ -27,12 +27,8 @@ export const NewProjectAuthRequired: FC = ({ } openAuthorizeWindow({ host: ap.host, - scopes: ap.authProviderType === "GitHub" ? ["repo"] : ap.requirements?.default, onSuccess: async () => { - // TODO: Verify this works correctly - if (ap.authProviderType === "GitHub") { - authProviders.refetch(); - } + authProviders.refetch(); }, onError: (payload) => { console.error("Authorization failed", selectedProviderHost, payload); diff --git a/components/dashboard/src/projects/new-project/NewProjectRepoSelection.tsx b/components/dashboard/src/projects/new-project/NewProjectRepoSelection.tsx index 7cf489f1d0b22f..2fad3a5a90b949 100644 --- a/components/dashboard/src/projects/new-project/NewProjectRepoSelection.tsx +++ b/components/dashboard/src/projects/new-project/NewProjectRepoSelection.tsx @@ -4,7 +4,7 @@ * See License.AGPL.txt in the project root for license information. */ -import { AuthProviderInfo, Project } from "@gitpod/gitpod-protocol"; +import { Project } from "@gitpod/gitpod-protocol"; import { FC, useCallback, useEffect, useMemo, useState } from "react"; import { useAreGithubWebhooksUnauthorized, useIsGithubAppEnabled } from "../../data/git-providers/github-queries"; import { LinkButton } from "../../components/LinkButton"; @@ -22,9 +22,10 @@ import { NewProjectCreateFromURL } from "./NewProjectCreateFromURL"; import { useStateWithDebounce } from "../../hooks/use-state-with-debounce"; import { useFeatureFlag } from "../../data/featureflag-query"; import Alert from "../../components/Alert"; +import { AuthProviderDescription, AuthProviderType } from "@gitpod/public-api/lib/gitpod/v1/authprovider_pb"; type Props = { - selectedProvider?: AuthProviderInfo; + selectedProvider?: AuthProviderDescription; onProjectCreated: (project: Project) => void; onChangeGitProvider: () => void; }; @@ -59,7 +60,7 @@ export const NewProjectRepoSelection: FC = ({ selectedProvider, onProject // Memoized & derived values const noReposAvailable = !!(reposInAccounts?.length === 0 || areGitHubWebhooksUnauthorized); const isGitHub = selectedProvider?.host === "github.com"; - const isBitbucketServer = selectedProvider?.authProviderType === "BitbucketServer"; + const isBitbucketServer = selectedProvider?.type === AuthProviderType.BITBUCKET_SERVER; const enableBBSIncrementalSearch = isBitbucketServer && newProjectIncrementalRepoSearchBBS; const accounts = useMemo(() => { diff --git a/components/dashboard/src/provider-utils.tsx b/components/dashboard/src/provider-utils.tsx index 22cb8bfc03cfca..5dc255c93e2c1d 100644 --- a/components/dashboard/src/provider-utils.tsx +++ b/components/dashboard/src/provider-utils.tsx @@ -29,6 +29,21 @@ function iconForAuthProvider(type: string | AuthProviderType) { } } +export function toAuthProviderLabel(type: AuthProviderType) { + switch (type) { + case AuthProviderType.GITHUB: + return "GitHub"; + case AuthProviderType.GITLAB: + return "GitLab"; + case AuthProviderType.BITBUCKET: + return "Bitbucket Cloud"; + case AuthProviderType.BITBUCKET_SERVER: + return "Bitbucket Server"; + default: + return "Unknown type"; + } +} + function simplifyProviderName(host: string) { switch (host) { case "github.com": diff --git a/components/dashboard/src/user-settings/AuthEntryItem.tsx b/components/dashboard/src/user-settings/AuthEntryItem.tsx index d2d801faf3544c..55a52f83969d78 100644 --- a/components/dashboard/src/user-settings/AuthEntryItem.tsx +++ b/components/dashboard/src/user-settings/AuthEntryItem.tsx @@ -4,17 +4,17 @@ * See License.AGPL.txt in the project root for license information. */ -import { AuthProviderInfo } from "@gitpod/gitpod-protocol"; import { useState } from "react"; import { ContextMenuEntry } from "../components/ContextMenu"; import { Item, ItemFieldIcon, ItemField, ItemFieldContextMenu } from "../components/ItemsList"; +import { AuthProviderDescription } from "@gitpod/public-api/lib/gitpod/v1/authprovider_pb"; interface AuthEntryItemParams { - ap: AuthProviderInfo; + ap: AuthProviderDescription; isConnected: (authProviderId: string) => boolean; getUsername: (authProviderId: string) => string | undefined; getPermissions: (authProviderId: string) => string[] | undefined; - gitProviderMenu: (provider: AuthProviderInfo) => ContextMenuEntry[]; + gitProviderMenu: (provider: AuthProviderDescription) => ContextMenuEntry[]; } export const AuthEntryItem = (props: AuthEntryItemParams) => { @@ -25,32 +25,32 @@ export const AuthEntryItem = (props: AuthEntryItemParams) => { }; return ( - +
 
- {props.ap.authProviderType} + {props.ap.type} {props.ap.host} - {props.getUsername(props.ap.authProviderId) || "–"} + {props.getUsername(props.ap.id) || "–"} Username - {props.getPermissions(props.ap.authProviderId)?.join(", ") || "–"} + {props.getPermissions(props.ap.id)?.join(", ") || "–"} Permissions diff --git a/components/dashboard/src/user-settings/Integrations.tsx b/components/dashboard/src/user-settings/Integrations.tsx index 24a8700ba11991..bd196a0def60b7 100644 --- a/components/dashboard/src/user-settings/Integrations.tsx +++ b/components/dashboard/src/user-settings/Integrations.tsx @@ -4,12 +4,12 @@ * See License.AGPL.txt in the project root for license information. */ -import { AuthProviderEntry, AuthProviderInfo, User } from "@gitpod/gitpod-protocol"; +import { AuthProviderEntry, User } from "@gitpod/gitpod-protocol"; import { SelectAccountPayload } from "@gitpod/gitpod-protocol/lib/auth"; import { useQuery } from "@tanstack/react-query"; import React, { useCallback, useContext, useEffect, useState } from "react"; import Alert from "../components/Alert"; -import { CheckboxInputField, CheckboxListField } from "../components/forms/CheckboxInputField"; +import { CheckboxListField } from "../components/forms/CheckboxInputField"; import ConfirmationModal from "../components/ConfirmationModal"; import { ContextMenuEntry } from "../components/ContextMenu"; import { Delayed } from "../components/Delayed"; @@ -20,16 +20,17 @@ import Modal, { ModalBody, ModalHeader, ModalFooter } from "../components/Modal" import { Heading2, Subheading } from "../components/typography/headings"; import copy from "../images/copy.svg"; import exclamation from "../images/exclamation.svg"; -import { openAuthorizeWindow } from "../provider-utils"; +import { openAuthorizeWindow, toAuthProviderLabel } from "../provider-utils"; import { getGitpodService, gitpodHostUrl } from "../service/service"; import { UserContext } from "../user-context"; import { AuthEntryItem } from "./AuthEntryItem"; import { IntegrationEntryItem } from "./IntegrationItemEntry"; import { PageWithSettingsSubMenu } from "./PageWithSettingsSubMenu"; import { SelectAccountModal } from "./SelectAccountModal"; -import { useAuthProviders } from "../data/auth-providers/auth-provider-query"; +import { useAuthProviderDescriptions } from "../data/auth-providers/auth-provider-query"; import { useFeatureFlag } from "../data/featureflag-query"; import { EmptyMessage } from "../components/EmptyMessage"; +import { AuthProviderDescription } from "@gitpod/public-api/lib/gitpod/v1/authprovider_pb"; export default function Integrations() { return ( @@ -46,11 +47,13 @@ export default function Integrations() { function GitProviders() { const { user, setUser } = useContext(UserContext); - const authProviders = useAuthProviders(); + const authProviders = useAuthProviderDescriptions(); const [allScopes, setAllScopes] = useState>(new Map()); - const [disconnectModal, setDisconnectModal] = useState<{ provider: AuthProviderInfo } | undefined>(undefined); + const [disconnectModal, setDisconnectModal] = useState<{ provider: AuthProviderDescription } | undefined>( + undefined, + ); const [editModal, setEditModal] = useState< - { provider: AuthProviderInfo; prevScopes: Set; nextScopes: Set } | undefined + { provider: AuthProviderDescription; prevScopes: Set; nextScopes: Set } | undefined >(undefined); const [selectAccountModal, setSelectAccountModal] = useState(undefined); const [errorMessage, setErrorMessage] = useState(); @@ -59,14 +62,14 @@ function GitProviders() { if (user) { const scopesByProvider = new Map(); const connectedProviders = user.identities.map((i) => - authProviders.data?.find((ap) => ap.authProviderId === i.authProviderId), + authProviders.data?.find((ap) => ap.id === i.authProviderId), ); for (let provider of connectedProviders) { if (!provider) { continue; } const token = await getGitpodService().server.getToken({ host: provider.host }); - scopesByProvider.set(provider.authProviderId, token?.scopes?.slice() || []); + scopesByProvider.set(provider.id, token?.scopes?.slice() || []); } setAllScopes(scopesByProvider); } @@ -80,29 +83,27 @@ function GitProviders() { return !!user?.identities?.find((i) => i.authProviderId === authProviderId); }; - const gitProviderMenu = (provider: AuthProviderInfo) => { + const gitProviderMenu = (provider: AuthProviderDescription) => { const result: ContextMenuEntry[] = []; - const connected = isConnected(provider.authProviderId); + const connected = isConnected(provider.id); if (connected) { result.push({ title: "Edit Permissions", onClick: () => startEditPermissions(provider), - separator: !provider.settingsUrl, + // separator: !provider.settingsUrl, }); - if (provider.settingsUrl) { - result.push({ - title: `Manage on ${provider.host}`, - onClick: () => { - window.open(provider.settingsUrl, "_blank", "noopener,noreferrer"); - }, - separator: true, - }); - } + // if (provider.settingsUrl) { + // result.push({ + // title: `Manage on ${provider.host}`, + // onClick: () => { + // window.open(provider.settingsUrl, "_blank", "noopener,noreferrer"); + // }, + // separator: true, + // }); + // } const canDisconnect = (user && User.isOrganizationOwned(user)) || - authProviders.data?.some( - (p) => p.authProviderId !== provider.authProviderId && isConnected(p.authProviderId), - ); + authProviders.data?.some((p) => p.id !== provider.id && isConnected(p.id)); if (canDisconnect) { result.push({ title: "Disconnect", @@ -128,11 +129,11 @@ function GitProviders() { return allScopes.get(authProviderId); }; - const connect = async (ap: AuthProviderInfo) => { - await doAuthorize(ap.host, ap.requirements?.default); + const connect = async (ap: AuthProviderDescription) => { + await doAuthorize(ap.host); }; - const disconnect = async (ap: AuthProviderInfo) => { + const disconnect = async (ap: AuthProviderDescription) => { setDisconnectModal(undefined); const returnTo = gitpodHostUrl.with({ pathname: "complete-auth", search: "message=success" }).toString(); const deauthorizeUrl = gitpodHostUrl @@ -157,7 +158,7 @@ function GitProviders() { ); }; - const startEditPermissions = async (provider: AuthProviderInfo) => { + const startEditPermissions = async (provider: AuthProviderDescription) => { // todo: add spinner const token = await getGitpodService().server.getToken({ host: provider.host }); @@ -207,58 +208,58 @@ function GitProviders() { } setEditModal(undefined); }; - const onChangeScopeHandler = (checked: boolean, scope: string) => { - if (!editModal) { - return; - } - - const nextScopes = new Set(editModal.nextScopes); - if (checked) { - nextScopes.add(scope); - } else { - nextScopes.delete(scope); - } - 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 ""; - } - }; + // const onChangeScopeHandler = (checked: boolean, scope: string) => { + // if (!editModal) { + // return; + // } + + // const nextScopes = new Set(editModal.nextScopes); + // if (checked) { + // nextScopes.add(scope); + // } else { + // nextScopes.delete(scope); + // } + // 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 (
@@ -271,7 +272,7 @@ function GitProviders() { title="Disconnect Provider" areYouSureText="Are you sure you want to disconnect the following provider?" children={{ - name: disconnectModal.provider.authProviderType, + name: toAuthProviderLabel(disconnectModal.provider.type), description: disconnectModal.provider.host, }} buttonText="Disconnect Provider" @@ -296,18 +297,19 @@ function GitProviders() { Edit Permissions - {(editModal.provider.scopes || []).map((scope) => ( + {/* TODO getScopesForType(editModal.provider.type) */} + {/* {(editModal.provider.scopes || []).map((scope) => ( onChangeScopeHandler(checked, scope)} /> - ))} + ))} */} @@ -340,7 +342,7 @@ function GitProviders() { ) : ( authProviders.data.map((ap) => ( = ({ title, message, l export const RepositoryNotFound: FC<{ error: StartWorkspaceError }> = ({ error }) => { const { host, owner, userIsOwner, userScopes = [], lastUpdate } = error.data || {}; - const authProviders = useAuthProviders(); + const authProviders = useAuthProviderDescriptions(); const authProvider = authProviders.data?.find((a) => a.host === host); if (!authProvider) { return ; } // TODO: this should be aware of already granted permissions - const missingScope = authProvider.authProviderType === "GitHub" ? "repo" : "read_repository"; + const missingScope = + authProvider.type === AuthProviderType.GITHUB + ? "repo" + : authProvider.type === AuthProviderType.GITLAB + ? "api" + : ""; const authorizeURL = gitpodHostUrl .withApi({ pathname: "/authorize",