Selaa lähdekoodia

update actions and secrets to use new auth

Ivan Galakhov 4 vuotta sitten
vanhempi
sitoutus
ad96e51a21

+ 1 - 0
internal/forms/git_action.go

@@ -28,6 +28,7 @@ func (ca *CreateGitAction) ToGitActionConfig() (*models.GitActionConfig, error)
 		DockerfilePath: ca.DockerfilePath,
 		FolderPath:     ca.FolderPath,
 		GitRepoID:      ca.GitRepoID,
+		IsInstallation: true,
 	}, nil
 }
 

+ 44 - 17
internal/integrations/ci/actions/actions.go

@@ -4,12 +4,13 @@ import (
 	"context"
 	"encoding/base64"
 	"fmt"
-
+	"github.com/bradleyfalzon/ghinstallation"
 	"github.com/google/go-github/v33/github"
 	"github.com/porter-dev/porter/internal/models"
 	"github.com/porter-dev/porter/internal/repository"
 	"golang.org/x/crypto/nacl/box"
 	"golang.org/x/oauth2"
+	"net/http"
 
 	"strings"
 
@@ -24,7 +25,9 @@ type GithubActions struct {
 	GitRepoOwner   string
 	Repo           repository.Repository
 
-	GithubConf *oauth2.Config
+	GithubConf           *oauth2.Config // one of these will let us authenticate
+	GithubAppID          int64
+	GithubInstallationID uint
 
 	WebhookToken string
 	PorterToken  string
@@ -197,22 +200,40 @@ func (g *GithubActions) GetGithubActionYAML() ([]byte, error) {
 }
 
 func (g *GithubActions) getClient() (*github.Client, error) {
-	// get the oauth integration
-	oauthInt, err := g.Repo.OAuthIntegration.ReadOAuthIntegration(g.GitIntegration.OAuthIntegrationID)
 
-	if err != nil {
-		return nil, err
-	}
+	// in the case that this still uses the oauth integration
+	if g.GitIntegration != nil {
+
+		// get the oauth integration
+		oauthInt, err := g.Repo.OAuthIntegration.ReadOAuthIntegration(g.GitIntegration.OAuthIntegrationID)
 
-	tok := &oauth2.Token{
-		AccessToken:  string(oauthInt.AccessToken),
-		RefreshToken: string(oauthInt.RefreshToken),
-		TokenType:    "Bearer",
+		if err != nil {
+			return nil, err
+		}
+
+		tok := &oauth2.Token{
+			AccessToken:  string(oauthInt.AccessToken),
+			RefreshToken: string(oauthInt.RefreshToken),
+			TokenType:    "Bearer",
+		}
+
+		client := github.NewClient(g.GithubConf.Client(oauth2.NoContext, tok))
+
+		return client, nil
 	}
 
-	client := github.NewClient(g.GithubConf.Client(oauth2.NoContext, tok))
+	// authenticate as github app installation
+	itr, err := ghinstallation.NewKeyFromFile(
+		http.DefaultTransport,
+		g.GithubAppID,
+		int64(g.GithubInstallationID),
+		"/porter/docker/github_app_private_key.pem")
+
+	if err != nil {
+		return nil, err
+	}
 
-	return client, nil
+	return github.NewClient(&http.Client{Transport: itr}), nil
 }
 
 func (g *GithubActions) createGithubSecret(
@@ -352,10 +373,13 @@ func (g *GithubActions) commitGithubFile(
 		Content: contents,
 		Branch:  github.String(branch),
 		SHA:     &sha,
-		Committer: &github.CommitAuthor{
+	}
+
+	if g.GitIntegration != nil {
+		opts.Committer = &github.CommitAuthor{
 			Name:  github.String("Porter Bot"),
 			Email: github.String("contact@getporter.dev"),
-		},
+		}
 	}
 
 	resp, _, err := client.Repositories.UpdateFile(
@@ -397,10 +421,13 @@ func (g *GithubActions) deleteGithubFile(
 		Message: github.String(fmt.Sprintf("Delete %s file", filename)),
 		Branch:  github.String(g.defaultBranch),
 		SHA:     &sha,
-		Committer: &github.CommitAuthor{
+	}
+
+	if g.GitIntegration != nil {
+		opts.Committer = &github.CommitAuthor{
 			Name:  github.String("Porter Bot"),
 			Email: github.String("contact@getporter.dev"),
-		},
+		}
 	}
 
 	_, _, err := client.Repositories.DeleteFile(

+ 3 - 0
internal/models/gitrepo.go

@@ -69,6 +69,9 @@ type GitActionConfig struct {
 
 	// The build context
 	FolderPath string `json:"folder_path"`
+
+	// Determines on how authentication is performed on this action
+	IsInstallation bool `json:"is_installation"`
 }
 
 // GitActionConfigExternal is an external GitActionConfig to be shared over REST

+ 17 - 18
server/api/deploy_handler.go

@@ -354,10 +354,7 @@ func (app *App) HandleUninstallTemplate(w http.ResponseWriter, r *http.Request)
 				gr, err := app.Repo.GitRepo.ReadGitRepo(gitAction.GitRepoID)
 
 				if err != nil {
-					app.sendExternalError(err, http.StatusInternalServerError, HTTPError{
-						Code:   ErrReleaseReadData,
-						Errors: []string{"github repo integration not found"},
-					}, w)
+					gr = nil
 				}
 
 				repoSplit := strings.Split(gitAction.GitRepo, "/")
@@ -370,20 +367,22 @@ func (app *App) HandleUninstallTemplate(w http.ResponseWriter, r *http.Request)
 				}
 
 				gaRunner := &actions.GithubActions{
-					ServerURL:      app.ServerConf.ServerURL,
-					GitIntegration: gr,
-					GitRepoName:    repoSplit[1],
-					GitRepoOwner:   repoSplit[0],
-					Repo:           *app.Repo,
-					GithubConf:     app.GithubProjectConf,
-					WebhookToken:   release.WebhookToken,
-					ProjectID:      uint(projID),
-					ReleaseName:    name,
-					GitBranch:      gitAction.GitBranch,
-					DockerFilePath: gitAction.DockerfilePath,
-					FolderPath:     gitAction.FolderPath,
-					ImageRepoURL:   gitAction.ImageRepoURI,
-					BuildEnv:       cEnv.Container.Env.Normal,
+					ServerURL:            app.ServerConf.ServerURL,
+					GitIntegration:       gr,
+					GithubAppID:          app.GithubAppConf.AppID,
+					GithubInstallationID: gitAction.GitRepoID,
+					GitRepoName:          repoSplit[1],
+					GitRepoOwner:         repoSplit[0],
+					Repo:                 *app.Repo,
+					GithubConf:           app.GithubProjectConf,
+					WebhookToken:         release.WebhookToken,
+					ProjectID:            uint(projID),
+					ReleaseName:          name,
+					GitBranch:            gitAction.GitBranch,
+					DockerFilePath:       gitAction.DockerfilePath,
+					FolderPath:           gitAction.FolderPath,
+					ImageRepoURL:         gitAction.ImageRepoURI,
+					BuildEnv:             cEnv.Container.Env.Normal,
 				}
 
 				err = gaRunner.Cleanup()

+ 17 - 23
server/api/git_action_handler.go

@@ -115,14 +115,6 @@ func (app *App) createGitActionFromForm(
 		return nil
 	}
 
-	// read the git repo
-	gr, err := app.Repo.GitRepo.ReadGitRepo(gitAction.GitRepoID)
-
-	if err != nil {
-		app.handleErrorFormDecoding(err, ErrProjectDecode, w)
-		return nil
-	}
-
 	repoSplit := strings.Split(gitAction.GitRepo, "/")
 
 	if len(repoSplit) != 2 {
@@ -164,21 +156,23 @@ func (app *App) createGitActionFromForm(
 
 	// create the commit in the git repo
 	gaRunner := &actions.GithubActions{
-		ServerURL:      app.ServerConf.ServerURL,
-		GitIntegration: gr,
-		GitRepoName:    repoSplit[1],
-		GitRepoOwner:   repoSplit[0],
-		Repo:           *app.Repo,
-		GithubConf:     app.GithubProjectConf,
-		WebhookToken:   release.WebhookToken,
-		ProjectID:      uint(projID),
-		ReleaseName:    name,
-		GitBranch:      gitAction.GitBranch,
-		DockerFilePath: gitAction.DockerfilePath,
-		FolderPath:     gitAction.FolderPath,
-		ImageRepoURL:   gitAction.ImageRepoURI,
-		PorterToken:    encoded,
-		BuildEnv:       form.BuildEnv,
+		ServerURL:            app.ServerConf.ServerURL,
+		GitIntegration:       nil,
+		GithubAppID:          app.GithubAppConf.AppID,
+		GithubInstallationID: form.GitRepoID,
+		GitRepoName:          repoSplit[1],
+		GitRepoOwner:         repoSplit[0],
+		Repo:                 *app.Repo,
+		GithubConf:           app.GithubProjectConf,
+		WebhookToken:         release.WebhookToken,
+		ProjectID:            uint(projID),
+		ReleaseName:          name,
+		GitBranch:            gitAction.GitBranch,
+		DockerFilePath:       gitAction.DockerfilePath,
+		FolderPath:           gitAction.FolderPath,
+		ImageRepoURL:         gitAction.ImageRepoURI,
+		PorterToken:          encoded,
+		BuildEnv:             form.BuildEnv,
 	}
 
 	_, err = gaRunner.Setup()

+ 34 - 36
server/api/release_handler.go

@@ -939,29 +939,28 @@ func (app *App) HandleUpgradeRelease(w http.ResponseWriter, r *http.Request) {
 				gr, err := app.Repo.GitRepo.ReadGitRepo(gitAction.GitRepoID)
 
 				if err != nil {
-					app.sendExternalError(err, http.StatusInternalServerError, HTTPError{
-						Code:   ErrReleaseReadData,
-						Errors: []string{"github repo integration not found"},
-					}, w)
+					gr = nil
 				}
 
 				repoSplit := strings.Split(gitAction.GitRepo, "/")
 
 				gaRunner := &actions.GithubActions{
-					ServerURL:      app.ServerConf.ServerURL,
-					GitIntegration: gr,
-					GitRepoName:    repoSplit[1],
-					GitRepoOwner:   repoSplit[0],
-					Repo:           *app.Repo,
-					GithubConf:     app.GithubProjectConf,
-					WebhookToken:   release.WebhookToken,
-					ProjectID:      uint(projID),
-					ReleaseName:    name,
-					GitBranch:      gitAction.GitBranch,
-					DockerFilePath: gitAction.DockerfilePath,
-					FolderPath:     gitAction.FolderPath,
-					ImageRepoURL:   gitAction.ImageRepoURI,
-					BuildEnv:       cEnv.Container.Env.Normal,
+					ServerURL:            app.ServerConf.ServerURL,
+					GitIntegration:       gr,
+					GithubInstallationID: gitAction.GitRepoID,
+					GithubAppID:          app.GithubAppConf.AppID,
+					GitRepoName:          repoSplit[1],
+					GitRepoOwner:         repoSplit[0],
+					Repo:                 *app.Repo,
+					GithubConf:           app.GithubProjectConf,
+					WebhookToken:         release.WebhookToken,
+					ProjectID:            uint(projID),
+					ReleaseName:          name,
+					GitBranch:            gitAction.GitBranch,
+					DockerFilePath:       gitAction.DockerfilePath,
+					FolderPath:           gitAction.FolderPath,
+					ImageRepoURL:         gitAction.ImageRepoURI,
+					BuildEnv:             cEnv.Container.Env.Normal,
 				}
 
 				err = gaRunner.CreateEnvSecret()
@@ -1324,10 +1323,7 @@ func (app *App) HandleRollbackRelease(w http.ResponseWriter, r *http.Request) {
 				gr, err := app.Repo.GitRepo.ReadGitRepo(gitAction.GitRepoID)
 
 				if err != nil {
-					app.sendExternalError(err, http.StatusInternalServerError, HTTPError{
-						Code:   ErrReleaseReadData,
-						Errors: []string{"github repo integration not found"},
-					}, w)
+					gr = nil
 				}
 
 				repoSplit := strings.Split(gitAction.GitRepo, "/")
@@ -1340,20 +1336,22 @@ func (app *App) HandleRollbackRelease(w http.ResponseWriter, r *http.Request) {
 				}
 
 				gaRunner := &actions.GithubActions{
-					ServerURL:      app.ServerConf.ServerURL,
-					GitIntegration: gr,
-					GitRepoName:    repoSplit[1],
-					GitRepoOwner:   repoSplit[0],
-					Repo:           *app.Repo,
-					GithubConf:     app.GithubProjectConf,
-					WebhookToken:   release.WebhookToken,
-					ProjectID:      uint(projID),
-					ReleaseName:    name,
-					GitBranch:      gitAction.GitBranch,
-					DockerFilePath: gitAction.DockerfilePath,
-					FolderPath:     gitAction.FolderPath,
-					ImageRepoURL:   gitAction.ImageRepoURI,
-					BuildEnv:       cEnv.Container.Env.Normal,
+					ServerURL:            app.ServerConf.ServerURL,
+					GitIntegration:       gr,
+					GithubInstallationID: gitAction.GitRepoID,
+					GithubAppID:          app.GithubAppConf.AppID,
+					GitRepoName:          repoSplit[1],
+					GitRepoOwner:         repoSplit[0],
+					Repo:                 *app.Repo,
+					GithubConf:           app.GithubProjectConf,
+					WebhookToken:         release.WebhookToken,
+					ProjectID:            uint(projID),
+					ReleaseName:          name,
+					GitBranch:            gitAction.GitBranch,
+					DockerFilePath:       gitAction.DockerfilePath,
+					FolderPath:           gitAction.FolderPath,
+					ImageRepoURL:         gitAction.ImageRepoURI,
+					BuildEnv:             cEnv.Container.Env.Normal,
 				}
 
 				err = gaRunner.CreateEnvSecret()