Преглед изворни кода

Merge pull request #524 from porter-dev/master

Merge to staging
abelanger5 пре 5 година
родитељ
комит
9ac8a96996

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

@@ -297,6 +297,22 @@ const getBranchContents = baseApi<
   return `/api/projects/${pathParams.project_id}/gitrepos/${pathParams.git_repo_id}/repos/${pathParams.kind}/${pathParams.owner}/${pathParams.name}/${pathParams.branch}/contents`;
 });
 
+const getProcfileContents = baseApi<
+  {
+    path: string;
+  },
+  {
+    project_id: number;
+    git_repo_id: number;
+    kind: string;
+    owner: string;
+    name: string;
+    branch: string;
+  }
+>("GET", (pathParams) => {
+  return `/api/projects/${pathParams.project_id}/gitrepos/${pathParams.git_repo_id}/repos/${pathParams.kind}/${pathParams.owner}/${pathParams.name}/${pathParams.branch}/procfile`;
+});
+
 const getBranches = baseApi<
   {},
   {
@@ -821,6 +837,7 @@ export default {
   getNamespaces,
   getNGINXIngresses,
   getOAuthIds,
+  getProcfileContents,
   getProjectClusters,
   getProjectRegistries,
   getProjectRepos,

+ 3 - 7
internal/kubernetes/domain/domain.go

@@ -3,11 +3,11 @@ package domain
 import (
 	"context"
 	"fmt"
-	"math/rand"
 	"net"
 	"strings"
 
 	"github.com/porter-dev/porter/internal/models"
+	"github.com/porter-dev/porter/internal/repository"
 	v1 "k8s.io/api/core/v1"
 	"k8s.io/api/extensions/v1beta1"
 	"k8s.io/client-go/kubernetes"
@@ -68,13 +68,9 @@ type CreateDNSRecordConfig struct {
 // NewDNSRecordForEndpoint generates a random subdomain and returns a DNSRecord
 // model
 func (c *CreateDNSRecordConfig) NewDNSRecordForEndpoint() *models.DNSRecord {
-	const allowed = "123456789abcdefghijklmnopqrstuvwxyz"
-	suffix := make([]byte, 8)
-	for i := range suffix {
-		suffix[i] = allowed[rand.Intn(len(allowed))]
-	}
+	suffix, _ := repository.GenerateRandomBytes(16)
 
-	subdomain := fmt.Sprintf("%s-%s", c.ReleaseName, string(suffix))
+	subdomain := fmt.Sprintf("%s-%s", c.ReleaseName, suffix)
 
 	return &models.DNSRecord{
 		SubdomainPrefix: subdomain,

+ 14 - 0
internal/repository/encrypt.go

@@ -4,6 +4,7 @@ import (
 	"crypto/aes"
 	"crypto/cipher"
 	"crypto/rand"
+	"encoding/base64"
 	"errors"
 	"io"
 )
@@ -21,6 +22,19 @@ func NewEncryptionKey() *[32]byte {
 	return &key
 }
 
+// NewRandomString generates a random string.
+// It panics if the source of randomness fails.
+func GenerateRandomBytes(n int) (string, error) {
+	b := make([]byte, n)
+	_, err := rand.Read(b)
+
+	if err != nil {
+		return "", err
+	}
+
+	return base64.URLEncoding.EncodeToString(b), nil
+}
+
 // Encrypt encrypts data using 256-bit AES-GCM.  This both hides the content of
 // the data and provides a check that it hasn't been altered. Output takes the
 // form nonce|ciphertext|tag where '|' indicates concatenation.

+ 7 - 7
server/api/deploy_handler.go

@@ -2,7 +2,6 @@ package api
 
 import (
 	"encoding/json"
-	"math/rand"
 	"net/http"
 	"net/url"
 	"strconv"
@@ -14,6 +13,7 @@ import (
 	"github.com/porter-dev/porter/internal/helm/loader"
 	"github.com/porter-dev/porter/internal/integrations/ci/actions"
 	"github.com/porter-dev/porter/internal/models"
+	"github.com/porter-dev/porter/internal/repository"
 	"gopkg.in/yaml.v2"
 )
 
@@ -116,11 +116,11 @@ func (app *App) HandleDeployTemplate(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	// generate 8 characters long webhook token.
-	const letters = "abcdefghijklmnopqrstuvwxyz"
-	token := make([]byte, 8)
-	for i := range token {
-		token[i] = letters[rand.Intn(len(letters))]
+	token, err := repository.GenerateRandomBytes(16)
+
+	if err != nil {
+		app.handleErrorInternal(err, w)
+		return
 	}
 
 	// create release with webhook token in db
@@ -129,7 +129,7 @@ func (app *App) HandleDeployTemplate(w http.ResponseWriter, r *http.Request) {
 		ProjectID:    form.ReleaseForm.Form.Cluster.ProjectID,
 		Namespace:    form.ReleaseForm.Form.Namespace,
 		Name:         form.ChartTemplateForm.Name,
-		WebhookToken: string(token),
+		WebhookToken: token,
 	}
 
 	_, err = app.Repo.Release.CreateRelease(release)

+ 0 - 2
server/api/git_action_handler.go

@@ -151,8 +151,6 @@ func (app *App) createGitActionFromForm(
 		return nil
 	}
 
-	fmt.Println("GIT ACTIONB BRANCH IS", gitAction.GitBranch)
-
 	// create the commit in the git repo
 	gaRunner := &actions.GithubActions{
 		GitIntegration: gr,

+ 61 - 0
server/api/git_repo_handler.go

@@ -6,7 +6,9 @@ import (
 	"fmt"
 	"net/http"
 	"net/url"
+	"regexp"
 	"strconv"
+	"strings"
 
 	"golang.org/x/oauth2"
 
@@ -202,6 +204,65 @@ func (app *App) HandleGetBranchContents(w http.ResponseWriter, r *http.Request)
 	json.NewEncoder(w).Encode(res)
 }
 
+type GetProcfileContentsResp map[string]string
+
+var procfileRegex = regexp.MustCompile("^([A-Za-z0-9_]+):\\s*(.+)$")
+
+// HandleGetProcfileContents retrieves the contents of a procfile in a github repo
+func (app *App) HandleGetProcfileContents(w http.ResponseWriter, r *http.Request) {
+	tok, err := app.githubTokenFromRequest(r)
+
+	if err != nil {
+		app.handleErrorInternal(err, w)
+		return
+	}
+
+	client := github.NewClient(app.GithubProjectConf.Client(oauth2.NoContext, tok))
+	owner := chi.URLParam(r, "owner")
+	name := chi.URLParam(r, "name")
+	branch := chi.URLParam(r, "branch")
+
+	queryParams, err := url.ParseQuery(r.URL.RawQuery)
+
+	if err != nil {
+		app.handleErrorFormDecoding(err, ErrReleaseDecode, w)
+		return
+	}
+
+	resp, _, _, err := client.Repositories.GetContents(
+		context.TODO(),
+		owner,
+		name,
+		queryParams["path"][0],
+		&github.RepositoryContentGetOptions{
+			Ref: branch,
+		},
+	)
+
+	if err != nil {
+		app.handleErrorInternal(err, w)
+		return
+	}
+
+	fileData, err := resp.GetContent()
+
+	if err != nil {
+		app.handleErrorInternal(err, w)
+		return
+	}
+
+	parsedContents := make(GetProcfileContentsResp)
+
+	// parse the procfile information
+	for _, line := range strings.Split(fileData, "\n") {
+		if matches := procfileRegex.FindStringSubmatch(line); matches != nil {
+			parsedContents[matches[1]] = matches[2]
+		}
+	}
+
+	json.NewEncoder(w).Encode(parsedContents)
+}
+
 // finds the github token given the git repo id and the project id
 func (app *App) githubTokenFromRequest(
 	r *http.Request,

+ 5 - 6
server/api/user_handler.go

@@ -4,7 +4,6 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"math/rand"
 	"net/http"
 	"net/url"
 	"strconv"
@@ -171,11 +170,11 @@ func (app *App) HandleCLILoginUser(w http.ResponseWriter, r *http.Request) {
 	}
 
 	// generate 64 characters long authorization code
-	const letters = "abcdefghijklmnopqrstuvwxyz123456789"
-	code := make([]byte, 64)
+	code, err := repository.GenerateRandomBytes(64)
 
-	for i := range code {
-		code[i] = letters[rand.Intn(len(letters))]
+	if err != nil {
+		app.handleErrorInternal(err, w)
+		return
 	}
 
 	expiry := time.Now().Add(30 * time.Second)
@@ -183,7 +182,7 @@ func (app *App) HandleCLILoginUser(w http.ResponseWriter, r *http.Request) {
 	// create auth code object and send back authorization code
 	authCode := &models.AuthCode{
 		Token:             encoded,
-		AuthorizationCode: string(code),
+		AuthorizationCode: code,
 		Expiry:            &expiry,
 	}
 

+ 14 - 0
server/router/router.go

@@ -1053,6 +1053,20 @@ func New(a *api.App) *chi.Mux {
 			),
 		)
 
+		r.Method(
+			"GET",
+			"/projects/{project_id}/gitrepos/{git_repo_id}/repos/{kind}/{owner}/{name}/{branch}/procfile",
+			auth.DoesUserHaveProjectAccess(
+				auth.DoesUserHaveGitRepoAccess(
+					requestlog.NewHandler(a.HandleGetProcfileContents, l),
+					mw.URLParam,
+					mw.URLParam,
+				),
+				mw.URLParam,
+				mw.ReadAccess,
+			),
+		)
+
 		// /api/projects/{project_id}/deploy routes
 		r.Method(
 			"POST",