Просмотр исходного кода

rename endpoints, finalize frontend user info display

Ivan Galakhov 4 лет назад
Родитель
Сommit
90f0718ac3

+ 90 - 6
dashboard/src/main/home/modals/AccountSettingsModal.tsx

@@ -1,10 +1,36 @@
-import React, { useContext } from "react";
+import React, { useContext, useEffect, useState } from "react";
 import styled from "styled-components";
 import close from "../../../assets/close.png";
 import { Context } from "../../../shared/Context";
+import api from "../../../shared/api";
+import Loading from "../../../components/Loading";
+
+interface GithubAppAccessData {
+  has_access: boolean;
+  username?: string;
+  accounts?: string[];
+}
 
 const AccountSettingsModal = () => {
   const { setCurrentModal } = useContext(Context);
+  const [accessLoading, setAccessLoading] = useState(true);
+  const [accessError, setAccessError] = useState(false);
+  const [accessData, setAccessData] = useState<GithubAppAccessData>({
+    has_access: false,
+  });
+
+  useEffect(() => {
+    api
+      .getGithubAccess("<token>", {}, {})
+      .then(({ data }) => {
+        setAccessData(data);
+        setAccessLoading(false);
+      })
+      .catch(() => {
+        setAccessError(true);
+        setAccessLoading(false);
+      });
+  }, []);
 
   return (
     <>
@@ -18,11 +44,57 @@ const AccountSettingsModal = () => {
       <ModalTitle>Account Settings</ModalTitle>
       <Subtitle>Github Integration</Subtitle>
       <br />
-      {/* Will be styled (and show what account is connected) later */}
-      No github integration detected. You can{" "}
-      <A href={"/api/integrations/github-app/install"}>
-        connect your GitHub account
-      </A>
+      {accessError ? (
+        <Placeholder>An error has occured.</Placeholder>
+      ) : accessLoading ? (
+        <LoadingWrapper>
+          {" "}
+          <Loading />
+        </LoadingWrapper>
+      ) : (
+        <>
+          {/* Will be styled (and show what account is connected) later */}
+          {accessData.has_access ? (
+            <Placeholder>
+              Authorized as <b>{accessData.username}</b> <br />
+              {!accessData.accounts || accessData.accounts.length == 0 ? (
+                <>
+                  It doesn't seem like the Porter application is installed in
+                  any repositories you have access to.
+                  <A href={"/api/integrations/github-app/install"}>
+                    Install the application in more repositories
+                  </A>
+                </>
+              ) : (
+                <>
+                  Additionally, porter has access to repos with the application
+                  installed in them in the following organizations and accounts:{" "}
+                  {accessData.accounts.map((name, i) => {
+                    return (
+                      <React.Fragment key={i}>
+                        <b>{name}</b>
+                        {i == accessData.accounts.length - 1 ? "" : ", "}
+                      </React.Fragment>
+                    );
+                  })}{" "}
+                  <br />
+                  Don't see the right repos?{" "}
+                  <A href={"/api/integrations/github-app/install"}>
+                    Install the application in more repositories
+                  </A>
+                </>
+              )}
+            </Placeholder>
+          ) : (
+            <>
+              No github integration detected. You can
+              <A href={"/api/integrations/github-app/authorize"}>
+                connect your GitHub account
+              </A>
+            </>
+          )}
+        </>
+      )}
     </>
   );
 };
@@ -83,3 +155,15 @@ const A = styled.a`
   margin-left: 5px;
   cursor: pointer;
 `;
+
+const LoadingWrapper = styled.div`
+  height: 50px;
+`;
+
+const Placeholder = styled.div`
+  color: #aaaabb;
+  font-size: 13px;
+  margin-left: 0px;
+  line-height: 1.6em;
+  user-select: none;
+`;

+ 5 - 0
dashboard/src/shared/api.tsx

@@ -732,6 +732,10 @@ const linkGithubProject = baseApi<
   return `/api/oauth/projects/${pathParams.project_id}/github`;
 });
 
+const getGithubAccess = baseApi<{}, {}>("GET", () => {
+  return `/api/integrations/github-app/access`;
+});
+
 const logInUser = baseApi<{
   email: string;
   password: string;
@@ -996,6 +1000,7 @@ export default {
   getTemplates,
   getUser,
   linkGithubProject,
+  getGithubAccess,
   listConfigMaps,
   logInUser,
   logOutUser,

+ 1 - 0
internal/config/config.go

@@ -43,6 +43,7 @@ type ServerConf struct {
 
 	GithubAppClientID     string `env:"GITHUB_APP_CLIENT_ID"`
 	GithubAppClientSecret string `env:"GITHUB_APP_CLIENT_SECRET"`
+	GithubAppName         string `env:"GITHUB_APP_NAME"`
 
 	GoogleClientID         string `env:"GOOGLE_CLIENT_ID"`
 	GoogleClientSecret     string `env:"GOOGLE_CLIENT_SECRET"`

+ 18 - 9
internal/oauth/config.go

@@ -18,6 +18,12 @@ type Config struct {
 	BaseURL      string
 }
 
+// GithubAppConf is standard oauth2 config but it need to keeps track of the app name
+type GithubAppConf struct {
+	AppName string
+	oauth2.Config
+}
+
 func NewGithubClient(cfg *Config) *oauth2.Config {
 	return &oauth2.Config{
 		ClientID:     cfg.ClientID,
@@ -31,16 +37,19 @@ func NewGithubClient(cfg *Config) *oauth2.Config {
 	}
 }
 
-func NewGithubAppClient(cfg *Config) *oauth2.Config {
-	return &oauth2.Config{
-		ClientID:     cfg.ClientID,
-		ClientSecret: cfg.ClientSecret,
-		Endpoint: oauth2.Endpoint{
-			AuthURL:  "https://github.com/login/oauth/authorize",
-			TokenURL: "https://github.com/login/oauth/access_token",
+func NewGithubAppClient(cfg *Config, name string) *GithubAppConf {
+	return &GithubAppConf{
+		AppName: name,
+		Config: oauth2.Config{
+			ClientID:     cfg.ClientID,
+			ClientSecret: cfg.ClientSecret,
+			Endpoint: oauth2.Endpoint{
+				AuthURL:  "https://github.com/login/oauth/authorize",
+				TokenURL: "https://github.com/login/oauth/access_token",
+			},
+			RedirectURL: cfg.BaseURL + "/api/oauth/github-app/callback",
+			Scopes:      cfg.Scopes,
 		},
-		RedirectURL: cfg.BaseURL + "/api/oauth/github-app/callback",
-		Scopes:      cfg.Scopes,
 	}
 }
 

+ 3 - 3
server/api/api.go

@@ -81,7 +81,7 @@ type App struct {
 	// oauth-specific clients
 	GithubUserConf    *oauth2.Config
 	GithubProjectConf *oauth2.Config
-	GithubAppConf     *oauth2.Config
+	GithubAppConf     *oauth.GithubAppConf
 	DOConf            *oauth2.Config
 	GoogleUserConf    *oauth2.Config
 
@@ -178,13 +178,13 @@ func New(conf *AppConfig) (*App, error) {
 		app.Capabilities.GithubLogin = sc.GithubLoginEnabled
 	}
 
-	if sc.GithubAppClientID != "" && sc.GithubAppClientSecret != "" {
+	if sc.GithubAppClientID != "" && sc.GithubAppClientSecret != "" && sc.GithubAppName != "" {
 		app.GithubAppConf = oauth.NewGithubAppClient(&oauth.Config{
 			ClientID:     sc.GithubAppClientID,
 			ClientSecret: sc.GithubAppClientSecret,
 			Scopes:       []string{"read:user"},
 			BaseURL:      sc.ServerURL,
-		})
+		}, sc.GithubAppName)
 	}
 
 	if sc.GoogleClientID != "" && sc.GoogleClientSecret != "" {

+ 7 - 2
server/api/integration_handler.go

@@ -3,6 +3,7 @@ package api
 import (
 	"context"
 	"encoding/json"
+	"fmt"
 	"github.com/google/go-github/github"
 	"github.com/porter-dev/porter/internal/oauth"
 	"golang.org/x/oauth2"
@@ -433,8 +434,8 @@ func (app *App) HandleGithubAppEvent(w http.ResponseWriter, r *http.Request) {
 
 }
 
-// HandleGithubAppInstall starts the oauth2 flow for a project repo request.
-func (app *App) HandleGithubAppInstall(w http.ResponseWriter, r *http.Request) {
+// HandleGithubAppAuthorize starts the oauth2 flow for a project repo request.
+func (app *App) HandleGithubAppAuthorize(w http.ResponseWriter, r *http.Request) {
 	state := oauth.CreateRandomState()
 
 	err := app.populateOAuthSession(w, r, state, false)
@@ -450,6 +451,10 @@ func (app *App) HandleGithubAppInstall(w http.ResponseWriter, r *http.Request) {
 	http.Redirect(w, r, url, 302)
 }
 
+func (app *App) HandleGithubAppInstall(w http.ResponseWriter, r *http.Request) {
+	http.Redirect(w, r, fmt.Sprintf("https://github.com/apps/%s/installations/new", app.GithubAppConf.AppName), 302)
+}
+
 type HandleListGithubAppAccessResp struct {
 	HasAccess bool     `json:"has_access"`
 	LoginName string   `json:"username,omitempty"`

+ 6 - 0
server/router/router.go

@@ -182,6 +182,12 @@ func New(a *api.App) *chi.Mux {
 				requestlog.NewHandler(a.HandleGithubAppEvent, l),
 			)
 
+			r.Method(
+				"GET",
+				"/integrations/github-app/authorize",
+				requestlog.NewHandler(a.HandleGithubAppAuthorize, l),
+			)
+
 			r.Method(
 				"GET",
 				"/integrations/github-app/install",