Ver Fonte

add NewListOAuthHandler

Anukul Sangwan há 4 anos atrás
pai
commit
72ab20d451

+ 3 - 5
api/client/integration.go

@@ -7,6 +7,7 @@ import (
 	"net/http"
 	"strings"
 
+	"github.com/porter-dev/porter/api/types"
 	ints "github.com/porter-dev/porter/internal/models/integrations"
 )
 
@@ -148,14 +149,11 @@ func (c *Client) CreateBasicAuthIntegration(
 	return bodyResp, nil
 }
 
-// ListOAuthIntegrationResponse is the list of oauth integrations in a project
-type ListOAuthIntegrationResponse []ints.OAuthIntegrationExternal
-
 // ListOAuthIntegrations lists the oauth integrations in a project
 func (c *Client) ListOAuthIntegrations(
 	ctx context.Context,
 	projectID uint,
-) (ListOAuthIntegrationResponse, error) {
+) (types.ListOAuthResponse, error) {
 	req, err := http.NewRequest(
 		"GET",
 		fmt.Sprintf("%s/projects/%d/integrations/oauth", c.BaseURL, projectID),
@@ -167,7 +165,7 @@ func (c *Client) ListOAuthIntegrations(
 	}
 
 	req = req.WithContext(ctx)
-	bodyResp := &ListOAuthIntegrationResponse{}
+	bodyResp := &types.ListOAuthResponse{}
 
 	if httpErr, err := c.sendRequest(req, bodyResp, true); httpErr != nil || err != nil {
 		if httpErr != nil {

+ 44 - 0
api/server/handlers/project_integrations/list_oauth.go

@@ -0,0 +1,44 @@
+package project_integration
+
+import (
+	"net/http"
+
+	"github.com/porter-dev/porter/api/server/handlers"
+	"github.com/porter-dev/porter/api/server/shared"
+	"github.com/porter-dev/porter/api/server/shared/apierrors"
+	"github.com/porter-dev/porter/api/server/shared/config"
+	"github.com/porter-dev/porter/api/types"
+	"github.com/porter-dev/porter/internal/models"
+)
+
+type ListOAuthHandler struct {
+	handlers.PorterHandlerWriter
+}
+
+func NewListOAuthHandler(
+	config *config.Config,
+	writer shared.ResultWriter,
+) *ListOAuthHandler {
+	return &ListOAuthHandler{
+		PorterHandlerWriter: handlers.NewDefaultPorterHandler(config, nil, writer),
+	}
+}
+
+func (p *ListOAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	project, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+
+	oauthInts, err := p.Repo().OAuthIntegration().ListOAuthIntegrationsByProjectID(project.ID)
+
+	if err != nil {
+		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	var res types.ListOAuthResponse = make([]*types.OAuthIntegration, 0)
+
+	for _, oauthInt := range oauthInts {
+		res = append(res, oauthInt.ToOAuthIntegrationType())
+	}
+
+	p.WriteResult(w, r, res)
+}

+ 83 - 0
api/server/router/project_integration.go

@@ -0,0 +1,83 @@
+package router
+
+import (
+	"github.com/go-chi/chi"
+	project_integration "github.com/porter-dev/porter/api/server/handlers/project_integrations"
+	"github.com/porter-dev/porter/api/server/shared"
+	"github.com/porter-dev/porter/api/server/shared/config"
+	"github.com/porter-dev/porter/api/types"
+)
+
+func NewProjectIntegrationScopedRegisterer(children ...*Registerer) *Registerer {
+	return &Registerer{
+		GetRoutes: GetProjectIntegrationScopedRoutes,
+		Children:  children,
+	}
+}
+
+func GetProjectIntegrationScopedRoutes(
+	r chi.Router,
+	config *config.Config,
+	basePath *types.Path,
+	factory shared.APIEndpointFactory,
+	children ...*Registerer,
+) []*Route {
+	routes, projPath := getProjectIntegrationRoutes(r, config, basePath, factory)
+
+	if len(children) > 0 {
+		r.Route(projPath.RelativePath, func(r chi.Router) {
+			for _, child := range children {
+				childRoutes := child.GetRoutes(r, config, basePath, factory, child.Children...)
+
+				routes = append(routes, childRoutes...)
+			}
+		})
+	}
+
+	return routes
+}
+
+func getProjectIntegrationRoutes(
+	r chi.Router,
+	config *config.Config,
+	basePath *types.Path,
+	factory shared.APIEndpointFactory,
+) ([]*Route, *types.Path) {
+	relPath := "/integrations"
+
+	newPath := &types.Path{
+		Parent:       basePath,
+		RelativePath: relPath,
+	}
+
+	routes := make([]*Route, 0)
+
+	// GET /api/projects/{project_id}/integrations/oauth -> project_integrations.NewListOAuth
+	listOAuthEndpoint := factory.NewAPIEndpoint(
+		&types.APIRequestMetadata{
+			Verb:   types.APIVerbGet,
+			Method: types.HTTPVerbGet,
+			Path: &types.Path{
+				Parent:       basePath,
+				RelativePath: relPath + "/oauth",
+			},
+			Scopes: []types.PermissionScope{
+				types.UserScope,
+				types.ProjectScope,
+			},
+		},
+	)
+
+	listOAuthHandler := project_integration.NewListOAuthHandler(
+		config,
+		factory.GetResultWriter(),
+	)
+
+	routes = append(routes, &Route{
+		Endpoint: listOAuthEndpoint,
+		Handler:  listOAuthHandler,
+		Router:   r,
+	})
+
+	return routes, newPath
+}

+ 2 - 0
api/server/router/router.go

@@ -29,6 +29,7 @@ func NewAPIRouter(config *config.Config) *chi.Mux {
 	registryRegisterer := NewRegistryScopedRegisterer()
 	helmRepoRegisterer := NewHelmRepoScopedRegisterer()
 	inviteRegisterer := NewInviteScopedRegisterer()
+	projectIntegrationRegisterer := NewProjectIntegrationScopedRegisterer()
 	projRegisterer := NewProjectScopedRegisterer(
 		clusterRegisterer,
 		registryRegisterer,
@@ -36,6 +37,7 @@ func NewAPIRouter(config *config.Config) *chi.Mux {
 		inviteRegisterer,
 		gitInstallationRegisterer,
 		infraRegisterer,
+		projectIntegrationRegisterer,
 	)
 	userRegisterer := NewUserScopedRegisterer(projRegisterer)
 

+ 27 - 0
api/types/project_integration.go

@@ -0,0 +1,27 @@
+package types
+
+// The supported oauth mechanism clients
+const (
+	OAuthGithub       OAuthIntegrationClient = "github"
+	OAuthDigitalOcean OAuthIntegrationClient = "do"
+	OAuthGoogle       OAuthIntegrationClient = "google"
+)
+
+// OAuthIntegrationClient is the name of an OAuth mechanism client
+type OAuthIntegrationClient string
+
+// OAuthIntegration is an OAuthIntegration to be shared over REST
+type OAuthIntegration struct {
+	ID uint `json:"id"`
+
+	// The name of the auth mechanism
+	Client OAuthIntegrationClient `json:"client"`
+
+	// The id of the user that linked this auth mechanism
+	UserID uint `json:"user_id"`
+
+	// The project that this integration belongs to
+	ProjectID uint `json:"project_id"`
+}
+
+type ListOAuthResponse []*OAuthIntegration

+ 6 - 7
cli/cmd/connect/docr.go

@@ -7,9 +7,8 @@ import (
 	"time"
 
 	api "github.com/porter-dev/porter/api/client"
+	"github.com/porter-dev/porter/api/types"
 	"github.com/porter-dev/porter/cli/cmd/utils"
-
-	ints "github.com/porter-dev/porter/internal/models/integrations"
 )
 
 // DOCR creates a DOCR integration
@@ -30,11 +29,11 @@ func DOCR(
 	}
 
 	linkedDO := false
-	var doAuth ints.OAuthIntegrationExternal
+	var doAuth *types.OAuthIntegration
 
 	// iterate through oauth integrations to find do
 	for _, oauthInt := range oauthInts {
-		if oauthInt.Client == ints.OAuthDigitalOcean {
+		if oauthInt.Client == types.OAuthDigitalOcean {
 			linkedDO = true
 			doAuth = oauthInt
 			break
@@ -77,8 +76,8 @@ Registry URL: `))
 	return reg.ID, nil
 }
 
-func triggerDigitalOceanOAuth(client *api.Client, projectID uint) (ints.OAuthIntegrationExternal, error) {
-	var doAuth ints.OAuthIntegrationExternal
+func triggerDigitalOceanOAuth(client *api.Client, projectID uint) (*types.OAuthIntegration, error) {
+	var doAuth *types.OAuthIntegration
 
 	oauthURL := fmt.Sprintf("%s/oauth/projects/%d/digitalocean", client.BaseURL, projectID)
 
@@ -96,7 +95,7 @@ func triggerDigitalOceanOAuth(client *api.Client, projectID uint) (ints.OAuthInt
 
 		// iterate through oauth integrations to find do
 		for _, oauthInt := range oauthInts {
-			if oauthInt.Client == ints.OAuthDigitalOcean {
+			if oauthInt.Client == types.OAuthDigitalOcean {
 				linkedDO = true
 				doAuth = oauthInt
 				break

+ 3 - 3
internal/forms/helper_test.go

@@ -4,7 +4,7 @@ import (
 	"os"
 	"testing"
 
-	"github.com/porter-dev/porter/api/server/shared"
+	"github.com/porter-dev/porter/api/server/shared/config/env"
 	"github.com/porter-dev/porter/api/types"
 	"github.com/porter-dev/porter/internal/adapter"
 	"github.com/porter-dev/porter/internal/models"
@@ -32,7 +32,7 @@ type tester struct {
 func setupTestEnv(tester *tester, t *testing.T) {
 	t.Helper()
 
-	db, err := adapter.New(&shared.DBConf{
+	db, err := adapter.New(&env.DBConf{
 		EncryptionKey: "__random_strong_encryption_key__",
 		SQLLite:       true,
 		SQLLitePath:   tester.dbFileName,
@@ -208,7 +208,7 @@ func initOAuthIntegration(tester *tester, t *testing.T) {
 			AccessToken:  []byte("idtoken"),
 			RefreshToken: []byte("refreshtoken"),
 		},
-		Client:    ints.OAuthGithub,
+		Client:    types.OAuthGithub,
 		ProjectID: tester.initProjects[0].ID,
 		UserID:    tester.initUsers[0].ID,
 	}

+ 5 - 28
internal/models/integrations/oauth.go

@@ -1,20 +1,11 @@
 package integrations
 
 import (
+	"github.com/porter-dev/porter/api/types"
 	"gorm.io/gorm"
 	"time"
 )
 
-// OAuthIntegrationClient is the name of an OAuth mechanism client
-type OAuthIntegrationClient string
-
-// The supported oauth mechanism clients
-const (
-	OAuthGithub       OAuthIntegrationClient = "github"
-	OAuthDigitalOcean OAuthIntegrationClient = "do"
-	OAuthGoogle       OAuthIntegrationClient = "google"
-)
-
 // SharedOAuthModel stores general fields needed for OAuth Integration
 type SharedOAuthModel struct {
 	// The ID issued to the client
@@ -38,7 +29,7 @@ type OAuthIntegration struct {
 	SharedOAuthModel
 
 	// The name of the auth mechanism
-	Client OAuthIntegrationClient `json:"client"`
+	Client types.OAuthIntegrationClient `json:"client"`
 
 	// The id of the user that linked this auth mechanism
 	UserID uint `json:"user_id"`
@@ -61,23 +52,9 @@ type GithubAppOAuthIntegration struct {
 	UserID uint `json:"user_id"`
 }
 
-// OAuthIntegrationExternal is an OAuthIntegration to be shared over REST
-type OAuthIntegrationExternal struct {
-	ID uint `json:"id"`
-
-	// The name of the auth mechanism
-	Client OAuthIntegrationClient `json:"client"`
-
-	// The id of the user that linked this auth mechanism
-	UserID uint `json:"user_id"`
-
-	// The project that this integration belongs to
-	ProjectID uint `json:"project_id"`
-}
-
-// Externalize generates an external KubeIntegration to be shared over REST
-func (o *OAuthIntegration) Externalize() *OAuthIntegrationExternal {
-	return &OAuthIntegrationExternal{
+// ToOAuthIntegrationType generates an external OAuthIntegration to be shared over REST
+func (o *OAuthIntegration) ToOAuthIntegrationType() *types.OAuthIntegration {
+	return &types.OAuthIntegration{
 		ID:        o.ID,
 		Client:    o.Client,
 		UserID:    o.UserID,

+ 6 - 2
internal/models/integrations/slack.go

@@ -1,6 +1,10 @@
 package integrations
 
-import "gorm.io/gorm"
+import (
+	"gorm.io/gorm"
+
+	"github.com/porter-dev/porter/api/types"
+)
 
 // SlackIntegration is a webhook notifier to a specific channel in a Slack workspace.
 type SlackIntegration struct {
@@ -8,7 +12,7 @@ type SlackIntegration struct {
 	SharedOAuthModel
 
 	// The name of the auth mechanism
-	Client OAuthIntegrationClient `json:"client"`
+	Client types.OAuthIntegrationClient `json:"client"`
 
 	// The id of the user that linked this auth mechanism
 	UserID uint `json:"user_id"`

+ 3 - 2
internal/repository/gorm/auth_test.go

@@ -4,6 +4,7 @@ import (
 	"testing"
 
 	"github.com/go-test/deep"
+	"github.com/porter-dev/porter/api/types"
 	ints "github.com/porter-dev/porter/internal/models/integrations"
 	orm "gorm.io/gorm"
 )
@@ -290,7 +291,7 @@ func TestCreateOAuthIntegration(t *testing.T) {
 			AccessToken:  []byte("idtoken"),
 			RefreshToken: []byte("refreshtoken"),
 		},
-		Client:    ints.OAuthGithub,
+		Client:    types.OAuthGithub,
 		ProjectID: tester.initProjects[0].ID,
 		UserID:    tester.initUsers[0].ID,
 	}
@@ -352,7 +353,7 @@ func TestListOAuthIntegrationsByProjectID(t *testing.T) {
 			AccessToken:  []byte("idtoken"),
 			RefreshToken: []byte("refreshtoken"),
 		},
-		Client:    ints.OAuthGithub,
+		Client:    types.OAuthGithub,
 		ProjectID: tester.initProjects[0].ID,
 		UserID:    tester.initUsers[0].ID,
 	}

+ 1 - 1
internal/repository/gorm/helpers_test.go

@@ -281,7 +281,7 @@ func initOAuthIntegration(tester *tester, t *testing.T) {
 			AccessToken:  []byte("idtoken"),
 			RefreshToken: []byte("refreshtoken"),
 		},
-		Client:    ints.OAuthGithub,
+		Client:    types.OAuthGithub,
 		ProjectID: tester.initProjects[0].ID,
 		UserID:    tester.initUsers[0].ID,
 	}