From a306bf2c270a806895ddfd084e42aa8ec404a23b Mon Sep 17 00:00:00 2001 From: Raghunandan Date: Wed, 24 Jun 2020 12:18:37 +0200 Subject: [PATCH] Use new GithubAuth flow in GitOps plugin --- plugins/gitops-profiles/package.json | 2 +- plugins/gitops-profiles/src/api.ts | 22 +++++ .../components/ClusterList/ClusterList.tsx | 31 +++---- .../components/ClusterPage/ClusterPage.tsx | 29 ++++--- .../ProfileCatalog/ProfileCatalog.tsx | 51 ++++++++---- plugins/gitops-profiles/src/plugin.ts | 11 ++- plugins/gitops-profiles/src/routes.ts | 37 +++++++++ yarn.lock | 81 ++----------------- 8 files changed, 139 insertions(+), 125 deletions(-) create mode 100644 plugins/gitops-profiles/src/routes.ts diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index bfb0328909..67a76ef872 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -28,7 +28,7 @@ "@material-ui/lab": "4.0.0-alpha.45", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-router-dom": "^5.2.0", + "react-router-dom": "6.0.0-alpha.5", "react-use": "^14.2.0" }, "devDependencies": { diff --git a/plugins/gitops-profiles/src/api.ts b/plugins/gitops-profiles/src/api.ts index 20e4dc4307..3a14dea837 100644 --- a/plugins/gitops-profiles/src/api.ts +++ b/plugins/gitops-profiles/src/api.ts @@ -79,6 +79,14 @@ export interface ListClusterRequest { gitHubToken: string; } +export interface GithubUserInfoRequest { + accessToken: string; +} + +export interface GithubUserInfoResponse { + login: string; +} + export class FetchError extends Error { get name(): string { return this.constructor.name; @@ -100,6 +108,7 @@ export type GitOpsApi = { cloneClusterFromTemplate(req: CloneFromTemplateRequest): Promise; applyProfiles(req: ApplyProfileRequest): Promise; listClusters(req: ListClusterRequest): Promise; + fetchUserInfo(req: GithubUserInfoRequest): Promise; }; export const gitOpsApiRef = createApiRef({ @@ -116,6 +125,19 @@ export class GitOpsRestApi implements GitOpsApi { return await resp.json(); } + async fetchUserInfo( + req: GithubUserInfoRequest, + ): Promise { + const resp = await fetch(`https://api.github.com/user`, { + method: 'get', + headers: new Headers({ + Authorization: `token ${req.accessToken}`, + }), + }); + if (!resp.ok) throw await FetchError.forResponse(resp); + return await resp.json(); + } + async fetchLog(req: PollLogRequest): Promise { return await this.fetch(`/api/cluster/run-status`, { method: 'post', diff --git a/plugins/gitops-profiles/src/components/ClusterList/ClusterList.tsx b/plugins/gitops-profiles/src/components/ClusterList/ClusterList.tsx index 8e5aa15aa9..c4b94e2958 100644 --- a/plugins/gitops-profiles/src/components/ClusterList/ClusterList.tsx +++ b/plugins/gitops-profiles/src/components/ClusterList/ClusterList.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { FC } from 'react'; +import React, { FC, useState } from 'react'; import { Content, ContentHeader, @@ -25,32 +25,28 @@ import { Progress, HeaderLabel, useApi, + githubAuthApiRef, } from '@backstage/core'; import ClusterTable from '../ClusterTable/ClusterTable'; import { Button } from '@material-ui/core'; -import { useAsync, useLocalStorage } from 'react-use'; +import { useAsync } from 'react-use'; import { gitOpsApiRef, ListClusterStatusesResponse } from '../../api'; import { Alert } from '@material-ui/lab'; const ClusterList: FC<{}> = () => { - const [loginInfo] = useLocalStorage<{ - token: string; - username: string; - name: string; - }>('githubLoginDetails', { - token: '', - username: '', - name: 'Guest', - }); - const api = useApi(gitOpsApiRef); + const githubAuth = useApi(githubAuthApiRef); + const [githubUsername, setGithubUsername] = useState(String); const { loading, error, value } = useAsync( - () => { + async () => { + const accessToken = await githubAuth.getAccessToken(); + const userInfo = await api.fetchUserInfo({ accessToken }); + setGithubUsername(userInfo.login); return api.listClusters({ - gitHubToken: loginInfo.token, - gitHubUser: loginInfo.username, + gitHubToken: accessToken, + gitHubUser: githubUsername, }); }, ); @@ -73,9 +69,6 @@ const ClusterList: FC<{}> = () => { Please make sure that you start GitOps-API backend on localhost port 3008 before using this plugin. - - If you're Guest, please login via GitHub first. - ); @@ -100,7 +93,7 @@ const ClusterList: FC<{}> = () => { return (
- +
{content}
diff --git a/plugins/gitops-profiles/src/components/ClusterPage/ClusterPage.tsx b/plugins/gitops-profiles/src/components/ClusterPage/ClusterPage.tsx index d454278255..c66b0613b5 100644 --- a/plugins/gitops-profiles/src/components/ClusterPage/ClusterPage.tsx +++ b/plugins/gitops-profiles/src/components/ClusterPage/ClusterPage.tsx @@ -24,21 +24,16 @@ import { Progress, HeaderLabel, useApi, + githubAuthApiRef, } from '@backstage/core'; import { Link } from '@material-ui/core'; import { useParams } from 'react-router-dom'; -import { useLocalStorage } from 'react-use'; import { gitOpsApiRef, Status } from '../../api'; import { transformRunStatus } from '../ProfileCatalog'; const ClusterPage: FC<{}> = () => { const params = useParams() as { owner: string; repo: string }; - const [loginInfo] = useLocalStorage<{ - token: string; - username: string; - name: string; - }>('githubLoginDetails'); const [pollingLog, setPollingLog] = useState(true); const [runStatus, setRunStatus] = useState([]); @@ -46,6 +41,9 @@ const ClusterPage: FC<{}> = () => { const [showProgress, setShowProgress] = useState(true); const api = useApi(gitOpsApiRef); + const githubAuth = useApi(githubAuthApiRef); + const [githubAccessToken, setGithubAccessToken] = useState(String); + const [githubUsername, setGithubUsername] = useState(String); const columns = [ { field: 'status', title: 'Status' }, @@ -53,11 +51,22 @@ const ClusterPage: FC<{}> = () => { ]; useEffect(() => { + const fetchGithubUserInfo = async () => { + const accessToken = await githubAuth.getAccessToken(); + const userInfo = await api.fetchUserInfo({ accessToken }); + setGithubAccessToken(accessToken); + setGithubUsername(userInfo.login); + }; + + if (!githubAccessToken || !githubUsername) { + fetchGithubUserInfo(); + } + if (pollingLog) { const interval = setInterval(async () => { const resp = await api.fetchLog({ - gitHubToken: loginInfo.token, - gitHubUser: loginInfo.username, + gitHubToken: githubAccessToken, + gitHubUser: githubUsername, targetOrg: params.owner, targetRepo: params.repo, }); @@ -72,12 +81,12 @@ const ClusterPage: FC<{}> = () => { return () => clearInterval(interval); } return () => {}; - }, [pollingLog, api, loginInfo, params]); + }, [pollingLog, api, params, githubAuth, githubAccessToken, githubUsername]); return (
- +