Skip to content

Commit d80a5b4

Browse files
jankeromnesroboquat
authored andcommitted
[dashboard] Ensure 'github.com' always has the correct scopes when creating a New Project
1 parent e8ab358 commit d80a5b4

File tree

1 file changed

+59
-12
lines changed

1 file changed

+59
-12
lines changed

components/dashboard/src/projects/NewProject.tsx

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default function NewProject() {
2929
const [reposInAccounts, setReposInAccounts] = useState<ProviderRepository[]>([]);
3030
const [repoSearchFilter, setRepoSearchFilter] = useState<string>("");
3131
const [selectedAccount, setSelectedAccount] = useState<string | undefined>(undefined);
32-
const [showGitProviders, setShowGitProviders] = useState<boolean>(true);
32+
const [showGitProviders, setShowGitProviders] = useState<boolean>(false);
3333
const [selectedRepo, setSelectedRepo] = useState<ProviderRepository | undefined>(undefined);
3434
const [selectedTeamOrUser, setSelectedTeamOrUser] = useState<Team | User | undefined>(undefined);
3535

@@ -42,8 +42,7 @@ export default function NewProject() {
4242

4343
const [authProviders, setAuthProviders] = useState<AuthProviderInfo[]>([]);
4444
const [isGitHubAppEnabled, setIsGitHubAppEnabled] = useState<boolean>();
45-
46-
console.log("isGitHubAppEnabled", isGitHubAppEnabled);
45+
const [isGitHubWebhooksUnauthorized, setIsGitHubWebhooksUnauthorized] = useState<boolean>();
4746

4847
useEffect(() => {
4948
const { server } = getGitpodService();
@@ -67,7 +66,25 @@ export default function NewProject() {
6766
}
6867
}
6968
}
70-
}, [user, authProviders]);
69+
}, [user, authProviders, selectedProviderHost]);
70+
71+
useEffect(() => {
72+
setIsGitHubWebhooksUnauthorized(false);
73+
if (!authProviders || !selectedProviderHost || isGitHubAppEnabled) {
74+
return;
75+
}
76+
const ap = authProviders.find((ap) => ap.host === selectedProviderHost);
77+
if (!ap || ap.authProviderType !== "GitHub") {
78+
return;
79+
}
80+
getGitpodService()
81+
.server.getToken({ host: ap.host })
82+
.then((token) => {
83+
if (!token || !token.scopes.includes("repo")) {
84+
setIsGitHubWebhooksUnauthorized(true);
85+
}
86+
});
87+
}, [authProviders, isGitHubAppEnabled, selectedProviderHost]);
7188

7289
useEffect(() => {
7390
const params = new URLSearchParams(location.search);
@@ -215,6 +232,25 @@ export default function NewProject() {
215232
});
216233
};
217234

235+
const authorize = () => {
236+
const ap = authProviders.find((ap) => ap.host === selectedProviderHost);
237+
if (!ap) {
238+
return;
239+
}
240+
openAuthorizeWindow({
241+
host: ap.host,
242+
scopes: ap.authProviderType === "GitHub" ? ["repo"] : ap.requirements?.default,
243+
onSuccess: async () => {
244+
if (ap.authProviderType === "GitHub") {
245+
setIsGitHubWebhooksUnauthorized(false);
246+
}
247+
},
248+
onError: (payload) => {
249+
console.error("Authorization failed", selectedProviderHost, payload);
250+
},
251+
});
252+
};
253+
218254
const createProject = async (teamOrUser: Team | User, repo: ProviderRepository) => {
219255
if (!selectedProviderHost) {
220256
return;
@@ -298,10 +334,15 @@ export default function NewProject() {
298334
};
299335

300336
const renderSelectRepository = () => {
301-
const noReposAvailable = reposInAccounts.length === 0;
302-
const filteredRepos = Array.from(reposInAccounts).filter(
303-
(r) => r.account === selectedAccount && `${r.name}`.toLowerCase().includes(repoSearchFilter.toLowerCase()),
304-
);
337+
// Don't list GitHub projects if we cannot install webhooks on them (project creation would eventually fail)
338+
const noReposAvailable = reposInAccounts.length === 0 || isGitHubWebhooksUnauthorized;
339+
const filteredRepos = isGitHubWebhooksUnauthorized
340+
? []
341+
: Array.from(reposInAccounts).filter(
342+
(r) =>
343+
r.account === selectedAccount &&
344+
`${r.name}`.toLowerCase().includes(repoSearchFilter.toLowerCase()),
345+
);
305346
const icon = selectedAccount && accounts.get(selectedAccount)?.avatarUrl;
306347

307348
const showSearchInput = !!repoSearchFilter || filteredRepos.length > 0;
@@ -430,13 +471,19 @@ export default function NewProject() {
430471
<div>
431472
<div className="px-12 py-20 text-center text-gray-500 bg-gray-50 dark:bg-gray-800 rounded-xl">
432473
<span className="dark:text-gray-400">
433-
Additional authorization is required for our GitHub App to watch your
474+
Additional authorization is required for Gitpod to watch your GitHub
434475
repositories and trigger prebuilds.
435476
</span>
436477
<br />
437-
<button className="mt-6" onClick={() => reconfigure()}>
438-
Configure Gitpod App
439-
</button>
478+
{isGitHubWebhooksUnauthorized ? (
479+
<button className="mt-6" onClick={() => authorize()}>
480+
Authorize GitHub
481+
</button>
482+
) : (
483+
<button className="mt-6" onClick={() => reconfigure()}>
484+
Configure Gitpod App
485+
</button>
486+
)}
440487
</div>
441488
</div>
442489
)}

0 commit comments

Comments
 (0)