Alexander Belanger %!s(int64=4) %!d(string=hai) anos
pai
achega
cc8c5f191b

+ 1 - 0
api/server/handlers/cluster/create_candidate.go

@@ -0,0 +1 @@
+package cluster

+ 115 - 0
api/server/handlers/cluster/create_manual.go

@@ -0,0 +1,115 @@
+package cluster
+
+import (
+	"encoding/base64"
+	"fmt"
+	"net/http"
+	"regexp"
+
+	"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"
+	"github.com/porter-dev/porter/internal/repository"
+)
+
+type CreateClusterManualHandler struct {
+	handlers.PorterHandlerReadWriter
+}
+
+func NewCreateClusterManualHandler(
+	config *config.Config,
+	decoderValidator shared.RequestDecoderValidator,
+	writer shared.ResultWriter,
+) *CreateClusterManualHandler {
+	return &CreateClusterManualHandler{
+		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
+	}
+}
+
+func (c *CreateClusterManualHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	// read the project from context
+	proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+
+	request := &types.CreateClusterManualRequest{}
+
+	if ok := c.DecodeAndValidate(w, r, request); !ok {
+		return
+	}
+
+	cluster, err := getClusterModelFromManualRequest(c.Repo(), proj, request)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	cluster, err = c.Repo().Cluster().CreateCluster(cluster)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	c.WriteResult(w, r, cluster.ToClusterType())
+}
+
+func getClusterModelFromManualRequest(
+	repo repository.Repository,
+	project *models.Project,
+	request *types.CreateClusterManualRequest,
+) (*models.Cluster, error) {
+	var authMechanism models.ClusterAuth
+
+	if request.GCPIntegrationID != 0 {
+		authMechanism = models.GCP
+
+		// check that the integration exists
+		_, err := repo.GCPIntegration().ReadGCPIntegration(project.ID, request.GCPIntegrationID)
+
+		if err != nil {
+			return nil, fmt.Errorf("gcp integration not found")
+		}
+	} else if request.AWSIntegrationID != 0 {
+		authMechanism = models.AWS
+
+		// check that the integration exists
+		_, err := repo.AWSIntegration().ReadAWSIntegration(project.ID, request.AWSIntegrationID)
+
+		if err != nil {
+			return nil, fmt.Errorf("aws integration not found")
+		}
+	} else {
+		return nil, fmt.Errorf("must include aws or gcp integration id")
+	}
+
+	cert := make([]byte, 0)
+
+	if request.CertificateAuthorityData != "" {
+		// determine if data is base64 decoded using regex
+		re := regexp.MustCompile(`^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$`)
+
+		// if it matches the base64 regex, decode it
+		if re.MatchString(request.CertificateAuthorityData) {
+			decoded, err := base64.StdEncoding.DecodeString(request.CertificateAuthorityData)
+
+			if err != nil {
+				return nil, err
+			}
+
+			cert = []byte(decoded)
+		}
+	}
+
+	return &models.Cluster{
+		ProjectID:                project.ID,
+		AuthMechanism:            authMechanism,
+		Name:                     request.Name,
+		Server:                   request.Server,
+		GCPIntegrationID:         request.GCPIntegrationID,
+		AWSIntegrationID:         request.AWSIntegrationID,
+		CertificateAuthorityData: cert,
+	}, nil
+}

+ 1 - 1
api/server/handlers/registry/create.go

@@ -49,7 +49,7 @@ func (p *RegistryCreateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
 	}
 
 	if regModel.URL == "" && regModel.AWSIntegrationID != 0 {
-		url, err := registry.GetECRRegistryURL(p.Repo().AWSIntegration(), regModel.AWSIntegrationID)
+		url, err := registry.GetECRRegistryURL(p.Repo().AWSIntegration(), regModel.ProjectID, regModel.AWSIntegrationID)
 
 		if err != nil {
 			p.HandleAPIError(w, r, apierrors.NewErrInternal(err))

+ 3 - 3
api/server/handlers/registry/get_token.go

@@ -53,7 +53,7 @@ func (c *RegistryGetECRTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Re
 
 	for _, reg := range regs {
 		if reg.AWSIntegrationID != 0 {
-			awsInt, err := c.Repo().AWSIntegration().ReadAWSIntegration(reg.AWSIntegrationID)
+			awsInt, err := c.Repo().AWSIntegration().ReadAWSIntegration(reg.ProjectID, reg.AWSIntegrationID)
 
 			if err != nil {
 				c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
@@ -187,7 +187,7 @@ func (c *RegistryGetDOCRTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.R
 
 	for _, reg := range regs {
 		if reg.DOIntegrationID != 0 && strings.Contains(reg.URL, request.ServerURL) {
-			oauthInt, err := c.Repo().OAuthIntegration().ReadOAuthIntegration(reg.DOIntegrationID)
+			oauthInt, err := c.Repo().OAuthIntegration().ReadOAuthIntegration(reg.ProjectID, reg.DOIntegrationID)
 
 			if err != nil {
 				c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
@@ -249,7 +249,7 @@ func (c *RegistryGetDockerhubTokenHandler) ServeHTTP(w http.ResponseWriter, r *h
 
 	for _, reg := range regs {
 		if reg.BasicIntegrationID != 0 && strings.Contains(reg.URL, "index.docker.io") {
-			basic, err := c.Repo().BasicIntegration().ReadBasicIntegration(reg.BasicIntegrationID)
+			basic, err := c.Repo().BasicIntegration().ReadBasicIntegration(reg.ProjectID, reg.BasicIntegrationID)
 
 			if err != nil {
 				c.HandleAPIError(w, r, apierrors.NewErrInternal(err))

+ 28 - 0
api/server/router/cluster.go

@@ -54,6 +54,34 @@ func getClusterRoutes(
 
 	routes := make([]*Route, 0)
 
+	// POST /api/projects/{project_id}/clusters -> project.NewCreateClusterManualHandler
+	createEndpoint := factory.NewAPIEndpoint(
+		&types.APIRequestMetadata{
+			Verb:   types.APIVerbCreate,
+			Method: types.HTTPVerbPost,
+			Path: &types.Path{
+				Parent:       basePath,
+				RelativePath: "/clusters",
+			},
+			Scopes: []types.PermissionScope{
+				types.UserScope,
+				types.ProjectScope,
+			},
+		},
+	)
+
+	createHandler := cluster.NewCreateClusterManualHandler(
+		config,
+		factory.GetDecoderValidator(),
+		factory.GetResultWriter(),
+	)
+
+	routes = append(routes, &Route{
+		Endpoint: createEndpoint,
+		Handler:  createHandler,
+		Router:   r,
+	})
+
 	// GET /api/projects/{project_id}/clusters/{cluster_id} -> project.NewClusterGetHandler
 	getEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{

+ 11 - 0
api/types/cluster.go

@@ -78,3 +78,14 @@ type GetPodsRequest struct {
 	Namespace string   `schema:"namespace"`
 	Selectors []string `schema:"selectors"`
 }
+
+type CreateClusterManualRequest struct {
+	Name      string `json:"name" form:"required"`
+	ProjectID uint   `json:"project_id" form:"required"`
+	Server    string `json:"server" form:"required"`
+
+	GCPIntegrationID uint `json:"gcp_integration_id"`
+	AWSIntegrationID uint `json:"aws_integration_id"`
+
+	CertificateAuthorityData string `json:"certificate_authority_data,omitempty"`
+}

+ 1 - 1
docs/developing/backend-refactor-status.md

@@ -37,7 +37,7 @@
 | <li>- [ ] `POST /api/projects/{project_id}/ci/actions/create`                                                               |             |                 |             |                  |
 | <li>- [ ] `POST /api/projects/{project_id}/ci/actions/generate`                                                             |             |                 |             |                  |
 | <li>- [x] `GET /api/projects/{project_id}/clusters`                                                                         | AB          |                 |             | yes              |
-| <li>- [ ] `POST /api/projects/{project_id}/clusters`                                                                        |             |                 |             |                  |
+| <li>- [X] `POST /api/projects/{project_id}/clusters`                                                                        | AB          |                 |             |                  |
 | <li>- [ ] `POST /api/projects/{project_id}/clusters/candidates`                                                             |             |                 |             |                  |
 | <li>- [ ] `GET /api/projects/{project_id}/clusters/candidates`                                                              |             |                 |             |                  |
 | <li>- [ ] `POST /api/projects/{project_id}/clusters/candidates/{candidate_id}/resolve`                                      |             |                 |             |                  |

+ 2 - 2
internal/helm/postrenderer.go

@@ -404,7 +404,7 @@ func (d *DockerSecretsPostRenderer) isRegistryNative(regName string) bool {
 
 	if strings.Contains(regName, "gcr") && d.Cluster.AuthMechanism == models.GCP {
 		// get the project id of the cluster
-		gcpInt, err := d.Repo.GCPIntegration().ReadGCPIntegration(d.Cluster.GCPIntegrationID)
+		gcpInt, err := d.Repo.GCPIntegration().ReadGCPIntegration(d.Cluster.ProjectID, d.Cluster.GCPIntegrationID)
 
 		if err != nil {
 			return false
@@ -432,7 +432,7 @@ func (d *DockerSecretsPostRenderer) isRegistryNative(regName string) bool {
 		eksAccountID := matches[1]
 		eksRegion := matches[3]
 
-		awsInt, err := d.Repo.AWSIntegration().ReadAWSIntegration(d.Cluster.AWSIntegrationID)
+		awsInt, err := d.Repo.AWSIntegration().ReadAWSIntegration(d.Cluster.ProjectID, d.Cluster.AWSIntegrationID)
 
 		if err != nil {
 			return false

+ 2 - 0
internal/helm/repo/repo.go

@@ -40,6 +40,7 @@ func (hr *HelmRepo) listChartsBasic(
 ) (types.ListTemplatesResponse, error) {
 	// get the basic auth integration
 	basic, err := repo.BasicIntegration().ReadBasicIntegration(
+		hr.ProjectID,
 		hr.BasicAuthIntegrationID,
 	)
 
@@ -67,6 +68,7 @@ func (hr *HelmRepo) getChartBasic(
 ) (*chart.Chart, error) {
 	// get the basic auth integration
 	basic, err := repo.BasicIntegration().ReadBasicIntegration(
+		hr.ProjectID,
 		hr.BasicAuthIntegrationID,
 	)
 

+ 1 - 1
internal/integrations/ci/actions/actions.go

@@ -199,7 +199,7 @@ func (g *GithubActions) getClient() (*github.Client, error) {
 	if g.GithubOAuthIntegration != nil {
 
 		// get the oauth integration
-		oauthInt, err := g.Repo.OAuthIntegration().ReadOAuthIntegration(g.GithubOAuthIntegration.OAuthIntegrationID)
+		oauthInt, err := g.Repo.OAuthIntegration().ReadOAuthIntegration(g.ProjectID, g.GithubOAuthIntegration.OAuthIntegrationID)
 
 		if err != nil {
 			return nil, err

+ 2 - 0
internal/kubernetes/agent.go

@@ -1038,6 +1038,7 @@ func (a *Agent) ProvisionDOCR(
 ) (*batchv1.Job, error) {
 	// get the token
 	oauthInt, err := repo.OAuthIntegration().ReadOAuthIntegration(
+		projectID,
 		infra.DOIntegrationID,
 	)
 
@@ -1090,6 +1091,7 @@ func (a *Agent) ProvisionDOKS(
 ) (*batchv1.Job, error) {
 	// get the token
 	oauthInt, err := repo.OAuthIntegration().ReadOAuthIntegration(
+		projectID,
 		infra.DOIntegrationID,
 	)
 

+ 8 - 0
internal/kubernetes/config.go

@@ -181,6 +181,7 @@ func (conf *OutOfClusterConfig) GetClientConfigFromCluster() (clientcmd.ClientCo
 
 	if conf.Cluster.AuthMechanism == models.Local {
 		kubeAuth, err := conf.Repo.KubeIntegration().ReadKubeIntegration(
+			conf.Cluster.ProjectID,
 			conf.Cluster.KubeIntegrationID,
 		)
 
@@ -242,6 +243,7 @@ func (conf *OutOfClusterConfig) CreateRawConfigFromCluster() (*api.Config, error
 	switch cluster.AuthMechanism {
 	case models.X509:
 		kubeAuth, err := conf.Repo.KubeIntegration().ReadKubeIntegration(
+			cluster.ProjectID,
 			cluster.KubeIntegrationID,
 		)
 
@@ -253,6 +255,7 @@ func (conf *OutOfClusterConfig) CreateRawConfigFromCluster() (*api.Config, error
 		authInfoMap[authInfoName].ClientKeyData = kubeAuth.ClientKeyData
 	case models.Basic:
 		kubeAuth, err := conf.Repo.KubeIntegration().ReadKubeIntegration(
+			cluster.ProjectID,
 			cluster.KubeIntegrationID,
 		)
 
@@ -264,6 +267,7 @@ func (conf *OutOfClusterConfig) CreateRawConfigFromCluster() (*api.Config, error
 		authInfoMap[authInfoName].Password = string(kubeAuth.Password)
 	case models.Bearer:
 		kubeAuth, err := conf.Repo.KubeIntegration().ReadKubeIntegration(
+			cluster.ProjectID,
 			cluster.KubeIntegrationID,
 		)
 
@@ -274,6 +278,7 @@ func (conf *OutOfClusterConfig) CreateRawConfigFromCluster() (*api.Config, error
 		authInfoMap[authInfoName].Token = string(kubeAuth.Token)
 	case models.OIDC:
 		oidcAuth, err := conf.Repo.OIDCIntegration().ReadOIDCIntegration(
+			cluster.ProjectID,
 			cluster.OIDCIntegrationID,
 		)
 
@@ -294,6 +299,7 @@ func (conf *OutOfClusterConfig) CreateRawConfigFromCluster() (*api.Config, error
 		}
 	case models.GCP:
 		gcpAuth, err := conf.Repo.GCPIntegration().ReadGCPIntegration(
+			cluster.ProjectID,
 			cluster.GCPIntegrationID,
 		)
 
@@ -315,6 +321,7 @@ func (conf *OutOfClusterConfig) CreateRawConfigFromCluster() (*api.Config, error
 		authInfoMap[authInfoName].Token = tok.AccessToken
 	case models.AWS:
 		awsAuth, err := conf.Repo.AWSIntegration().ReadAWSIntegration(
+			cluster.ProjectID,
 			cluster.AWSIntegrationID,
 		)
 
@@ -332,6 +339,7 @@ func (conf *OutOfClusterConfig) CreateRawConfigFromCluster() (*api.Config, error
 		authInfoMap[authInfoName].Token = tok
 	case models.DO:
 		oauthInt, err := conf.Repo.OAuthIntegration().ReadOAuthIntegration(
+			cluster.ProjectID,
 			cluster.DOIntegrationID,
 		)
 

+ 1 - 1
internal/kubernetes/provisioner/global_stream.go

@@ -136,7 +136,7 @@ func GlobalStreamListener(
 						json.Unmarshal([]byte(dataString), reg)
 					}
 
-					awsInt, err := repo.AWSIntegration().ReadAWSIntegration(reg.AWSIntegrationID)
+					awsInt, err := repo.AWSIntegration().ReadAWSIntegration(reg.ProjectID, reg.AWSIntegrationID)
 
 					if err != nil {
 						continue

+ 17 - 2
internal/registry/registry.go

@@ -57,8 +57,8 @@ type Image struct {
 	PushedAt *time.Time `json:"pushed_at"`
 }
 
-func GetECRRegistryURL(awsIntRepo repository.AWSIntegrationRepository, awsIntID uint) (string, error) {
-	awsInt, err := awsIntRepo.ReadAWSIntegration(awsIntID)
+func GetECRRegistryURL(awsIntRepo repository.AWSIntegrationRepository, projectID, awsIntID uint) (string, error) {
+	awsInt, err := awsIntRepo.ReadAWSIntegration(projectID, awsIntID)
 
 	if err != nil {
 		return "", err
@@ -119,6 +119,7 @@ func (r *Registry) GetGCRToken(repo repository.Repository) (*ints.TokenCache, er
 	getTokenCache := r.getTokenCacheFunc(repo)
 
 	gcp, err := repo.GCPIntegration().ReadGCPIntegration(
+		r.ProjectID,
 		r.GCPIntegrationID,
 	)
 
@@ -151,6 +152,7 @@ func (r *Registry) listGCRRepositories(
 	repo repository.Repository,
 ) ([]*Repository, error) {
 	gcp, err := repo.GCPIntegration().ReadGCPIntegration(
+		r.ProjectID,
 		r.GCPIntegrationID,
 	)
 
@@ -206,6 +208,7 @@ func (r *Registry) listGCRRepositories(
 
 func (r *Registry) listECRRepositories(repo repository.Repository) ([]*Repository, error) {
 	aws, err := repo.AWSIntegration().ReadAWSIntegration(
+		r.ProjectID,
 		r.AWSIntegrationID,
 	)
 
@@ -245,6 +248,7 @@ func (r *Registry) listDOCRRepositories(
 	doAuth *oauth2.Config,
 ) ([]*Repository, error) {
 	oauthInt, err := repo.OAuthIntegration().ReadOAuthIntegration(
+		r.ProjectID,
 		r.DOIntegrationID,
 	)
 
@@ -303,6 +307,7 @@ func (r *Registry) listPrivateRegistryRepositories(
 	}
 
 	basic, err := repo.BasicIntegration().ReadBasicIntegration(
+		r.ProjectID,
 		r.BasicIntegrationID,
 	)
 
@@ -430,6 +435,7 @@ func (r *Registry) createECRRepository(
 	name string,
 ) error {
 	aws, err := repo.AWSIntegration().ReadAWSIntegration(
+		r.ProjectID,
 		r.AWSIntegrationID,
 	)
 
@@ -492,6 +498,7 @@ func (r *Registry) ListImages(
 
 func (r *Registry) listECRImages(repoName string, repo repository.Repository) ([]*Image, error) {
 	aws, err := repo.AWSIntegration().ReadAWSIntegration(
+		r.ProjectID,
 		r.AWSIntegrationID,
 	)
 
@@ -564,6 +571,7 @@ type gcrImageResp struct {
 
 func (r *Registry) listGCRImages(repoName string, repo repository.Repository) ([]*Image, error) {
 	gcp, err := repo.GCPIntegration().ReadGCPIntegration(
+		r.ProjectID,
 		r.GCPIntegrationID,
 	)
 
@@ -624,6 +632,7 @@ func (r *Registry) listDOCRImages(
 	doAuth *oauth2.Config,
 ) ([]*Image, error) {
 	oauthInt, err := repo.OAuthIntegration().ReadOAuthIntegration(
+		r.ProjectID,
 		r.DOIntegrationID,
 	)
 
@@ -672,6 +681,7 @@ func (r *Registry) listPrivateRegistryImages(repoName string, repo repository.Re
 	}
 
 	basic, err := repo.BasicIntegration().ReadBasicIntegration(
+		r.ProjectID,
 		r.BasicIntegrationID,
 	)
 
@@ -741,6 +751,7 @@ type dockerHubLoginResp struct {
 
 func (r *Registry) listDockerHubImages(repoName string, repo repository.Repository) ([]*Image, error) {
 	basic, err := repo.BasicIntegration().ReadBasicIntegration(
+		r.ProjectID,
 		r.BasicIntegrationID,
 	)
 
@@ -858,6 +869,7 @@ func (r *Registry) getECRDockerConfigFile(
 	repo repository.Repository,
 ) (*configfile.ConfigFile, error) {
 	aws, err := repo.AWSIntegration().ReadAWSIntegration(
+		r.ProjectID,
 		r.AWSIntegrationID,
 	)
 
@@ -914,6 +926,7 @@ func (r *Registry) getGCRDockerConfigFile(
 	repo repository.Repository,
 ) (*configfile.ConfigFile, error) {
 	gcp, err := repo.GCPIntegration().ReadGCPIntegration(
+		r.ProjectID,
 		r.GCPIntegrationID,
 	)
 
@@ -945,6 +958,7 @@ func (r *Registry) getDOCRDockerConfigFile(
 	doAuth *oauth2.Config,
 ) (*configfile.ConfigFile, error) {
 	oauthInt, err := repo.OAuthIntegration().ReadOAuthIntegration(
+		r.ProjectID,
 		r.DOIntegrationID,
 	)
 
@@ -981,6 +995,7 @@ func (r *Registry) getPrivateRegistryDockerConfigFile(
 	repo repository.Repository,
 ) (*configfile.ConfigFile, error) {
 	basic, err := repo.BasicIntegration().ReadBasicIntegration(
+		r.ProjectID,
 		r.BasicIntegrationID,
 	)
 

+ 12 - 12
internal/repository/gorm/auth.go

@@ -55,11 +55,11 @@ func (repo *KubeIntegrationRepository) CreateKubeIntegration(
 
 // ReadKubeIntegration finds a kube auth mechanism by id
 func (repo *KubeIntegrationRepository) ReadKubeIntegration(
-	id uint,
+	projectID, id uint,
 ) (*ints.KubeIntegration, error) {
 	ki := &ints.KubeIntegration{}
 
-	if err := repo.db.Where("id = ?", id).First(&ki).Error; err != nil {
+	if err := repo.db.Where("project_id = ? AND id = ?", projectID, id).First(&ki).Error; err != nil {
 		return nil, err
 	}
 
@@ -275,11 +275,11 @@ func (repo *BasicIntegrationRepository) CreateBasicIntegration(
 
 // ReadBasicIntegration finds a basic auth mechanism by id
 func (repo *BasicIntegrationRepository) ReadBasicIntegration(
-	id uint,
+	projectID, id uint,
 ) (*ints.BasicIntegration, error) {
 	basic := &ints.BasicIntegration{}
 
-	if err := repo.db.Where("id = ?", id).First(&basic).Error; err != nil {
+	if err := repo.db.Where("project_id = ? AND id = ?", projectID, id).First(&basic).Error; err != nil {
 		return nil, err
 	}
 
@@ -415,11 +415,11 @@ func (repo *OIDCIntegrationRepository) CreateOIDCIntegration(
 
 // ReadOIDCIntegration finds a oidc auth mechanism by id
 func (repo *OIDCIntegrationRepository) ReadOIDCIntegration(
-	id uint,
+	projectID, id uint,
 ) (*ints.OIDCIntegration, error) {
 	oidc := &ints.OIDCIntegration{}
 
-	if err := repo.db.Where("id = ?", id).First(&oidc).Error; err != nil {
+	if err := repo.db.Where("project_id = ? AND id = ?", projectID, id).First(&oidc).Error; err != nil {
 		return nil, err
 	}
 
@@ -635,11 +635,11 @@ func (repo *OAuthIntegrationRepository) CreateOAuthIntegration(
 
 // ReadOAuthIntegration finds a oauth auth mechanism by id
 func (repo *OAuthIntegrationRepository) ReadOAuthIntegration(
-	id uint,
+	projectID, id uint,
 ) (*ints.OAuthIntegration, error) {
 	oauth := &ints.OAuthIntegration{}
 
-	if err := repo.db.Where("id = ?", id).First(&oauth).Error; err != nil {
+	if err := repo.db.Where("project_id = ? AND id = ?", projectID, id).First(&oauth).Error; err != nil {
 		return nil, err
 	}
 
@@ -818,11 +818,11 @@ func (repo *GCPIntegrationRepository) CreateGCPIntegration(
 
 // ReadGCPIntegration finds a gcp auth mechanism by id
 func (repo *GCPIntegrationRepository) ReadGCPIntegration(
-	id uint,
+	projectID, id uint,
 ) (*ints.GCPIntegration, error) {
 	gcp := &ints.GCPIntegration{}
 
-	if err := repo.db.Where("id = ?", id).First(&gcp).Error; err != nil {
+	if err := repo.db.Where("project_id = ? AND id = ?", projectID, id).First(&gcp).Error; err != nil {
 		return nil, err
 	}
 
@@ -955,11 +955,11 @@ func (repo *AWSIntegrationRepository) OverwriteAWSIntegration(
 
 // ReadAWSIntegration finds a aws auth mechanism by id
 func (repo *AWSIntegrationRepository) ReadAWSIntegration(
-	id uint,
+	projectID, id uint,
 ) (*ints.AWSIntegration, error) {
 	aws := &ints.AWSIntegration{}
 
-	if err := repo.db.Where("id = ?", id).First(&aws).Error; err != nil {
+	if err := repo.db.Where("project_id = ? AND id = ?", projectID, id).First(&aws).Error; err != nil {
 		return nil, err
 	}
 

+ 8 - 8
internal/repository/gorm/auth_test.go

@@ -33,7 +33,7 @@ func TestCreateKubeIntegration(t *testing.T) {
 		t.Fatalf("%v\n", err)
 	}
 
-	ki, err = tester.repo.KubeIntegration().ReadKubeIntegration(ki.Model.ID)
+	ki, err = tester.repo.KubeIntegration().ReadKubeIntegration(tester.initProjects[0].ID, ki.Model.ID)
 
 	if err != nil {
 		t.Fatalf("%v\n", err)
@@ -119,7 +119,7 @@ func TestCreateBasicIntegration(t *testing.T) {
 		t.Fatalf("%v\n", err)
 	}
 
-	basic, err = tester.repo.BasicIntegration().ReadBasicIntegration(basic.Model.ID)
+	basic, err = tester.repo.BasicIntegration().ReadBasicIntegration(tester.initProjects[0].ID, basic.Model.ID)
 
 	if err != nil {
 		t.Fatalf("%v\n", err)
@@ -209,7 +209,7 @@ func TestCreateOIDCIntegration(t *testing.T) {
 		t.Fatalf("%v\n", err)
 	}
 
-	oidc, err = tester.repo.OIDCIntegration().ReadOIDCIntegration(oidc.Model.ID)
+	oidc, err = tester.repo.OIDCIntegration().ReadOIDCIntegration(tester.initProjects[0].ID, oidc.Model.ID)
 
 	if err != nil {
 		t.Fatalf("%v\n", err)
@@ -303,7 +303,7 @@ func TestCreateOAuthIntegration(t *testing.T) {
 		t.Fatalf("%v\n", err)
 	}
 
-	oauth, err = tester.repo.OAuthIntegration().ReadOAuthIntegration(oauth.Model.ID)
+	oauth, err = tester.repo.OAuthIntegration().ReadOAuthIntegration(tester.initProjects[0].ID, oauth.Model.ID)
 
 	if err != nil {
 		t.Fatalf("%v\n", err)
@@ -394,7 +394,7 @@ func TestCreateGCPIntegration(t *testing.T) {
 		t.Fatalf("%v\n", err)
 	}
 
-	gcp, err = tester.repo.GCPIntegration().ReadGCPIntegration(gcp.Model.ID)
+	gcp, err = tester.repo.GCPIntegration().ReadGCPIntegration(tester.initProjects[0].ID, gcp.Model.ID)
 
 	if err != nil {
 		t.Fatalf("%v\n", err)
@@ -483,7 +483,7 @@ func TestCreateAWSIntegration(t *testing.T) {
 		t.Fatalf("%v\n", err)
 	}
 
-	aws, err = tester.repo.AWSIntegration().ReadAWSIntegration(aws.Model.ID)
+	aws, err = tester.repo.AWSIntegration().ReadAWSIntegration(tester.initProjects[0].ID, aws.Model.ID)
 
 	if err != nil {
 		t.Fatalf("%v\n", err)
@@ -514,7 +514,7 @@ func TestOverwriteAWSIntegration(t *testing.T) {
 	initAWSIntegration(tester, t)
 	defer cleanup(tester, t)
 
-	aws, err := tester.repo.AWSIntegration().ReadAWSIntegration(1)
+	aws, err := tester.repo.AWSIntegration().ReadAWSIntegration(tester.initProjects[0].ID, 1)
 
 	if err != nil {
 		t.Fatalf("%v\n", err)
@@ -529,7 +529,7 @@ func TestOverwriteAWSIntegration(t *testing.T) {
 		t.Fatalf("%v\n", err)
 	}
 
-	gotAWS, err := tester.repo.AWSIntegration().ReadAWSIntegration(1)
+	gotAWS, err := tester.repo.AWSIntegration().ReadAWSIntegration(tester.initProjects[0].ID, 1)
 
 	expAWS := &ints.AWSIntegration{
 		ProjectID:          tester.initProjects[0].ID,

+ 6 - 6
internal/repository/integrations.go

@@ -8,7 +8,7 @@ import (
 // mechanism
 type KubeIntegrationRepository interface {
 	CreateKubeIntegration(am *ints.KubeIntegration) (*ints.KubeIntegration, error)
-	ReadKubeIntegration(id uint) (*ints.KubeIntegration, error)
+	ReadKubeIntegration(projectID, id uint) (*ints.KubeIntegration, error)
 	ListKubeIntegrationsByProjectID(projectID uint) ([]*ints.KubeIntegration, error)
 }
 
@@ -16,7 +16,7 @@ type KubeIntegrationRepository interface {
 // mechanism
 type BasicIntegrationRepository interface {
 	CreateBasicIntegration(am *ints.BasicIntegration) (*ints.BasicIntegration, error)
-	ReadBasicIntegration(id uint) (*ints.BasicIntegration, error)
+	ReadBasicIntegration(projectID, id uint) (*ints.BasicIntegration, error)
 	ListBasicIntegrationsByProjectID(projectID uint) ([]*ints.BasicIntegration, error)
 }
 
@@ -24,7 +24,7 @@ type BasicIntegrationRepository interface {
 // mechanism
 type OIDCIntegrationRepository interface {
 	CreateOIDCIntegration(am *ints.OIDCIntegration) (*ints.OIDCIntegration, error)
-	ReadOIDCIntegration(id uint) (*ints.OIDCIntegration, error)
+	ReadOIDCIntegration(projectID, id uint) (*ints.OIDCIntegration, error)
 	ListOIDCIntegrationsByProjectID(projectID uint) ([]*ints.OIDCIntegration, error)
 }
 
@@ -32,7 +32,7 @@ type OIDCIntegrationRepository interface {
 // mechanism
 type OAuthIntegrationRepository interface {
 	CreateOAuthIntegration(am *ints.OAuthIntegration) (*ints.OAuthIntegration, error)
-	ReadOAuthIntegration(id uint) (*ints.OAuthIntegration, error)
+	ReadOAuthIntegration(projectID, id uint) (*ints.OAuthIntegration, error)
 	ListOAuthIntegrationsByProjectID(projectID uint) ([]*ints.OAuthIntegration, error)
 	UpdateOAuthIntegration(am *ints.OAuthIntegration) (*ints.OAuthIntegration, error)
 }
@@ -57,7 +57,7 @@ type SlackIntegrationRepository interface {
 type AWSIntegrationRepository interface {
 	CreateAWSIntegration(am *ints.AWSIntegration) (*ints.AWSIntegration, error)
 	OverwriteAWSIntegration(am *ints.AWSIntegration) (*ints.AWSIntegration, error)
-	ReadAWSIntegration(id uint) (*ints.AWSIntegration, error)
+	ReadAWSIntegration(projectID, id uint) (*ints.AWSIntegration, error)
 	ListAWSIntegrationsByProjectID(projectID uint) ([]*ints.AWSIntegration, error)
 }
 
@@ -65,7 +65,7 @@ type AWSIntegrationRepository interface {
 // mechanism
 type GCPIntegrationRepository interface {
 	CreateGCPIntegration(am *ints.GCPIntegration) (*ints.GCPIntegration, error)
-	ReadGCPIntegration(id uint) (*ints.GCPIntegration, error)
+	ReadGCPIntegration(projectID, id uint) (*ints.GCPIntegration, error)
 	ListGCPIntegrationsByProjectID(projectID uint) ([]*ints.GCPIntegration, error)
 }
 

+ 6 - 6
internal/repository/test/auth.go

@@ -39,7 +39,7 @@ func (repo *KubeIntegrationRepository) CreateKubeIntegration(
 
 // ReadKubeIntegration finds a kube auth mechanism by id
 func (repo *KubeIntegrationRepository) ReadKubeIntegration(
-	id uint,
+	projectID, id uint,
 ) (*ints.KubeIntegration, error) {
 	if !repo.canQuery {
 		return nil, errors.New("Cannot read from database")
@@ -103,7 +103,7 @@ func (repo *BasicIntegrationRepository) CreateBasicIntegration(
 
 // ReadBasicIntegration finds a basic auth mechanism by id
 func (repo *BasicIntegrationRepository) ReadBasicIntegration(
-	id uint,
+	projectID, id uint,
 ) (*ints.BasicIntegration, error) {
 	if !repo.canQuery {
 		return nil, errors.New("Cannot read from database")
@@ -167,7 +167,7 @@ func (repo *OIDCIntegrationRepository) CreateOIDCIntegration(
 
 // ReadOIDCIntegration finds a oidc auth mechanism by id
 func (repo *OIDCIntegrationRepository) ReadOIDCIntegration(
-	id uint,
+	projectID, id uint,
 ) (*ints.OIDCIntegration, error) {
 	if !repo.canQuery {
 		return nil, errors.New("Cannot read from database")
@@ -231,7 +231,7 @@ func (repo *OAuthIntegrationRepository) CreateOAuthIntegration(
 
 // ReadOAuthIntegration finds a o auth mechanism by id
 func (repo *OAuthIntegrationRepository) ReadOAuthIntegration(
-	id uint,
+	projectID, id uint,
 ) (*ints.OAuthIntegration, error) {
 	if !repo.canQuery {
 		return nil, errors.New("Cannot read from database")
@@ -330,7 +330,7 @@ func (repo *AWSIntegrationRepository) OverwriteAWSIntegration(
 
 // ReadAWSIntegration finds a aws auth mechanism by id
 func (repo *AWSIntegrationRepository) ReadAWSIntegration(
-	id uint,
+	projectID, id uint,
 ) (*ints.AWSIntegration, error) {
 	if !repo.canQuery {
 		return nil, errors.New("Cannot read from database")
@@ -394,7 +394,7 @@ func (repo *GCPIntegrationRepository) CreateGCPIntegration(
 
 // ReadGCPIntegration finds a gcp auth mechanism by id
 func (repo *GCPIntegrationRepository) ReadGCPIntegration(
-	id uint,
+	projectID, id uint,
 ) (*ints.GCPIntegration, error) {
 	if !repo.canQuery {
 		return nil, errors.New("Cannot read from database")