Skip to content

[papi]: Add GetSuggestedRepoURLs #18514

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions components/gitpod-protocol/go/gitpod-service.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type APIInterface interface {
GetWorkspaceOwner(ctx context.Context, workspaceID string) (res *UserInfo, err error)
GetWorkspaceUsers(ctx context.Context, workspaceID string) (res []*WorkspaceInstanceUser, err error)
GetFeaturedRepositories(ctx context.Context) (res []*WhitelistedRepository, err error)
GetSuggestedContextURLs(ctx context.Context) (res []*string, err error)
GetWorkspace(ctx context.Context, id string) (res *WorkspaceInfo, err error)
IsWorkspaceOwner(ctx context.Context, workspaceID string) (res bool, err error)
CreateWorkspace(ctx context.Context, options *CreateWorkspaceOptions) (res *WorkspaceCreationResult, err error)
Expand Down Expand Up @@ -140,6 +141,8 @@ const (
FunctionGetWorkspaceUsers FunctionName = "getWorkspaceUsers"
// FunctionGetFeaturedRepositories is the name of the getFeaturedRepositories function
FunctionGetFeaturedRepositories FunctionName = "getFeaturedRepositories"
// FunctionGetSuggestedContextURLs is the name of the getSuggestedContextURLs function
FunctionGetSuggestedContextURLs FunctionName = "getSuggestedContextURLs"
// FunctionGetWorkspace is the name of the getWorkspace function
FunctionGetWorkspace FunctionName = "getWorkspace"
// FunctionIsWorkspaceOwner is the name of the isWorkspaceOwner function
Expand Down Expand Up @@ -1020,6 +1023,24 @@ func (gp *APIoverJSONRPC) ClosePort(ctx context.Context, workspaceID string, por
return
}

// GetSuggestedContextURLs calls getSuggestedContextURLs on the server
func (gp *APIoverJSONRPC) GetSuggestedContextURLs(ctx context.Context) (res []*string, err error) {
if gp == nil {
err = errNotConnected
return
}
var _params []interface{}

var result []*string
err = gp.C.Call(ctx, "getSuggestedContextURLs", _params, &result)
if err != nil {
return
}
res = result

return
}

// UpdateGitStatus calls UpdateGitStatus on the server
func (gp *APIoverJSONRPC) UpdateGitStatus(ctx context.Context, workspaceID string, status *WorkspaceInstanceRepoStatus) (err error) {
if gp == nil {
Expand Down
88 changes: 44 additions & 44 deletions components/gitpod-protocol/go/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 51 additions & 0 deletions components/public-api-server/pkg/apiv1/scm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) 2023 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License.AGPL.txt in the project root for license information.

package apiv1

import (
"context"

connect "github.com/bufbuild/connect-go"
v1 "github.com/gitpod-io/gitpod/components/public-api/go/experimental/v1"
"github.com/gitpod-io/gitpod/components/public-api/go/experimental/v1/v1connect"
"github.com/gitpod-io/gitpod/public-api-server/pkg/proxy"
)

func NewSCMService(pool proxy.ServerConnectionPool) *SCMService {
return &SCMService{
connectionPool: pool,
}
}

var _ v1connect.SCMServiceHandler = (*SCMService)(nil)

type SCMService struct {
connectionPool proxy.ServerConnectionPool

v1connect.UnimplementedSCMServiceHandler
}

func (s *SCMService) GetSuggestedRepoURLs(ctx context.Context, req *connect.Request[v1.GetSuggestedRepoURLsRequest]) (*connect.Response[v1.GetSuggestedRepoURLsResponse], error) {
conn, err := getConnection(ctx, s.connectionPool)
if err != nil {
return nil, err
}

reposPtrs, err := conn.GetSuggestedContextURLs(ctx)
if err != nil {
return nil, proxy.ConvertError(err)
}

repos := make([]string, len(reposPtrs))
for i, repoPtr := range reposPtrs {
if repoPtr != nil {
repos[i] = *repoPtr
}
}

return connect.NewResponse(&v1.GetSuggestedRepoURLsResponse{
Repos: repos,
}), nil
}
71 changes: 71 additions & 0 deletions components/public-api-server/pkg/apiv1/scm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) 2023 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License.AGPL.txt in the project root for license information.

package apiv1

import (
"context"
"net/http"
"net/http/httptest"
"testing"

"github.com/bufbuild/connect-go"
"github.com/gitpod-io/gitpod/components/public-api/go/config"
v1 "github.com/gitpod-io/gitpod/components/public-api/go/experimental/v1"
"github.com/gitpod-io/gitpod/components/public-api/go/experimental/v1/v1connect"
protocol "github.com/gitpod-io/gitpod/gitpod-protocol"
"github.com/gitpod-io/gitpod/public-api-server/pkg/auth"
"github.com/gitpod-io/gitpod/public-api-server/pkg/jws"
"github.com/gitpod-io/gitpod/public-api-server/pkg/jws/jwstest"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
)

func TestSCMService_GetSuggestedRepoURLs(t *testing.T) {
t.Run("proxies request to server", func(t *testing.T) {
serverMock, client := setupSCMService(t)

str := ""
serverMock.EXPECT().GetSuggestedContextURLs(gomock.Any()).Return([]*string{&str}, nil)

retrieved, err := client.GetSuggestedRepoURLs(context.Background(), connect.NewRequest(&v1.GetSuggestedRepoURLsRequest{}))
require.NoError(t, err)
requireEqualProto(t, &v1.GetSuggestedRepoURLsResponse{
Repos: []string{""},
}, retrieved.Msg)
})
}

func setupSCMService(t *testing.T) (*protocol.MockAPIInterface, v1connect.SCMServiceClient) {
t.Helper()

ctrl := gomock.NewController(t)
t.Cleanup(ctrl.Finish)

serverMock := protocol.NewMockAPIInterface(ctrl)

svc := NewSCMService(&FakeServerConnPool{
api: serverMock,
})

keyset := jwstest.GenerateKeySet(t)
rsa256, err := jws.NewRSA256(keyset)
require.NoError(t, err)

_, handler := v1connect.NewSCMServiceHandler(svc, connect.WithInterceptors(auth.NewServerInterceptor(config.SessionConfig{
Issuer: "unitetest.com",
Cookie: config.CookieConfig{
Name: "cookie_jwt",
},
}, rsa256)))

srv := httptest.NewServer(handler)
t.Cleanup(srv.Close)

client := v1connect.NewSCMServiceClient(http.DefaultClient, srv.URL, connect.WithInterceptors(
auth.NewClientInterceptor("auth-token"),
))

return serverMock, client
}
5 changes: 3 additions & 2 deletions components/public-api-server/pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,15 @@ func Start(logger *logrus.Entry, version string, cfg *config.Configuration) erro

signer = auth.NewHS256Signer([]byte(personalACcessTokenSigningKey))
} else {
log.Info("No Personal Access Token signign key specified, PersonalAccessToken service will be disabled.")
log.Info("No Personal Access Token signing key specified, PersonalAccessToken service will be disabled.")
}

srv.HTTPMux().Handle("/stripe/invoices/webhook", handlers.ContentTypeHandler(stripeWebhookHandler, "application/json"))

oidcService := oidc.NewService(cfg.SessionServiceAddress, dbConn, cipherSet, hs256, 5*time.Minute)

if redisClient == nil {
return fmt.Errorf("no Redis configiured")
return fmt.Errorf("no Redis configured")
}
idpService, err := identityprovider.NewService(strings.TrimSuffix(cfg.PublicURL, "/")+"/idp", identityprovider.NewRedisCache(context.Background(), redisClient))
if err != nil {
Expand Down Expand Up @@ -198,6 +198,7 @@ func register(srv *baseserver.Server, deps *registerDependencies) error {
rootHandler.Mount(v1connect.NewWorkspacesServiceHandler(apiv1.NewWorkspaceService(deps.connPool, deps.expClient), handlerOptions...))
rootHandler.Mount(v1connect.NewTeamsServiceHandler(apiv1.NewTeamsService(deps.connPool), handlerOptions...))
rootHandler.Mount(v1connect.NewUserServiceHandler(apiv1.NewUserService(deps.connPool), handlerOptions...))
rootHandler.Mount(v1connect.NewSCMServiceHandler(apiv1.NewSCMService(deps.connPool), handlerOptions...))
rootHandler.Mount(v1connect.NewIDEClientServiceHandler(apiv1.NewIDEClientService(deps.connPool), handlerOptions...))
rootHandler.Mount(v1connect.NewProjectsServiceHandler(apiv1.NewProjectsService(deps.connPool), handlerOptions...))
rootHandler.Mount(v1connect.NewOIDCServiceHandler(apiv1.NewOIDCService(deps.connPool, deps.expClient, deps.dbConn, deps.cipher), handlerOptions...))
Expand Down
16 changes: 16 additions & 0 deletions components/public-api/gitpod/experimental/v1/scm.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
syntax = "proto3";

package gitpod.experimental.v1;

option go_package = "github.com/gitpod-io/gitpod/components/public-api/go/experimental/v1";

service SCMService {
// GetSuggestedRepoURLs returns a list of suggested repositories to open for
// the user.
rpc GetSuggestedRepoURLs(GetSuggestedRepoURLsRequest)
returns (GetSuggestedRepoURLsResponse) {}
}

message GetSuggestedRepoURLsRequest {}

message GetSuggestedRepoURLsResponse { repeated string repos = 1; }
Loading