From ff2f949e7841cc7afd816e7eb75f1ed2a40e48ee Mon Sep 17 00:00:00 2001 From: Johannes Batzill Date: Tue, 8 Nov 2022 19:35:49 -0800 Subject: [PATCH] add GITURL to repo apis list and create (#64) - rename repo.url to repo.GitURL to avoid ambiguity - add support to create / list api - add default value (http://localhost:3000) - remove handler backfilling host / port to simplify flow (can be added if needed) --- cli/server/harness.wire_gen.go | 2 +- cli/server/standalone.wire_gen.go | 2 +- internal/api/controller/repo/controller.go | 3 +++ internal/api/controller/repo/create.go | 6 +++++ internal/api/controller/repo/find.go | 25 ++++++++++++----- internal/api/controller/repo/wire.go | 3 ++- internal/api/controller/space/controller.go | 4 ++- .../api/controller/space/list_repositories.go | 8 ++++++ internal/api/controller/space/wire.go | 9 ++++--- internal/api/handler/repo/find.go | 27 ++----------------- internal/router/api.go | 10 +++---- types/config.go | 2 +- types/repo.go | 2 +- 13 files changed, 56 insertions(+), 47 deletions(-) diff --git a/cli/server/harness.wire_gen.go b/cli/server/harness.wire_gen.go index 8f27f562f..7ae0fc21e 100644 --- a/cli/server/harness.wire_gen.go +++ b/cli/server/harness.wire_gen.go @@ -80,7 +80,7 @@ func initSystem(ctx context.Context, config *types.Config) (*system, error) { repoStore := database.ProvideRepoStore(db, pathTransformation) serviceaccountController := serviceaccount.NewController(serviceAccount, authorizer, serviceAccountStore, spaceStore, repoStore, tokenStore) checkSpace := check.ProvideSpaceCheck() - spaceController := space.NewController(checkSpace, authorizer, spaceStore, repoStore, serviceAccountStore) + spaceController := space.ProvideController(config, checkSpace, authorizer, spaceStore, repoStore, serviceAccountStore) accountClient, err := client.ProvideAccountClient(serviceJWTProvider, typesConfig) if err != nil { return nil, err diff --git a/cli/server/standalone.wire_gen.go b/cli/server/standalone.wire_gen.go index 060412cf9..f6d88a889 100644 --- a/cli/server/standalone.wire_gen.go +++ b/cli/server/standalone.wire_gen.go @@ -55,7 +55,7 @@ func initSystem(ctx context.Context, config *types.Config) (*system, error) { } repoController := repo.ProvideController(config, checkRepo, authorizer, spaceStore, repoStore, serviceAccountStore, gitrpcInterface) checkSpace := check.ProvideSpaceCheck() - spaceController := space.NewController(checkSpace, authorizer, spaceStore, repoStore, serviceAccountStore) + spaceController := space.ProvideController(config, checkSpace, authorizer, spaceStore, repoStore, serviceAccountStore) serviceAccount := check.ProvideServiceAccountCheck() serviceaccountController := serviceaccount.NewController(serviceAccount, authorizer, serviceAccountStore, spaceStore, repoStore, tokenStore) apiHandler := router.ProvideAPIHandler(systemStore, authenticator, repoController, spaceController, serviceaccountController, controller) diff --git a/internal/api/controller/repo/controller.go b/internal/api/controller/repo/controller.go index 5aae97a67..b33973edd 100644 --- a/internal/api/controller/repo/controller.go +++ b/internal/api/controller/repo/controller.go @@ -13,6 +13,7 @@ import ( type Controller struct { defaultBranch string + gitBaseURL string repoCheck check.Repo authorizer authz.Authorizer spaceStore store.SpaceStore @@ -23,6 +24,7 @@ type Controller struct { func NewController( defaultBranch string, + gitBaseURL string, repoCheck check.Repo, authorizer authz.Authorizer, spaceStore store.SpaceStore, @@ -32,6 +34,7 @@ func NewController( ) *Controller { return &Controller{ defaultBranch: defaultBranch, + gitBaseURL: gitBaseURL, repoCheck: repoCheck, authorizer: authorizer, spaceStore: spaceStore, diff --git a/internal/api/controller/repo/create.go b/internal/api/controller/repo/create.go index b7a896200..5238e9897 100644 --- a/internal/api/controller/repo/create.go +++ b/internal/api/controller/repo/create.go @@ -139,6 +139,12 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea return nil, err } + // populate repo url + repo.GitURL, err = GenerateRepoGitURL(c.gitBaseURL, repo.Path) + if err != nil { + return nil, err + } + return repo, nil } diff --git a/internal/api/controller/repo/find.go b/internal/api/controller/repo/find.go index 521d8dc8a..0af8e355c 100644 --- a/internal/api/controller/repo/find.go +++ b/internal/api/controller/repo/find.go @@ -6,6 +6,7 @@ package repo import ( "context" + "fmt" "net/url" "path" "strings" @@ -17,8 +18,7 @@ import ( ) // Find finds a repo. -func (c *Controller) Find(ctx context.Context, session *auth.Session, repoRef string, - cfg *types.Config) (*types.Repository, error) { +func (c *Controller) Find(ctx context.Context, session *auth.Session, repoRef string) (*types.Repository, error) { repo, err := findRepoFromRef(ctx, c.repoStore, repoRef) if err != nil { return nil, err @@ -27,13 +27,24 @@ func (c *Controller) Find(ctx context.Context, session *auth.Session, repoRef st if err = apiauth.CheckRepo(ctx, c.authorizer, session, repo, enum.PermissionRepoView, true); err != nil { return nil, err } - repoPath := path.Clean(repo.Path) - if !strings.HasSuffix(repoPath, ".git") { - repoPath += ".git" - } - repo.URL, err = url.JoinPath(cfg.Git.BaseURL, repoPath) + + repo.GitURL, err = GenerateRepoGitURL(c.gitBaseURL, repo.Path) if err != nil { return nil, err } + return repo, nil } + +func GenerateRepoGitURL(gitBaseURL string, repoPath string) (string, error) { + repoPath = path.Clean(repoPath) + if !strings.HasSuffix(repoPath, ".git") { + repoPath += ".git" + } + gitURL, err := url.JoinPath(gitBaseURL, repoPath) + if err != nil { + return "", fmt.Errorf("failed to join base url '%s' with path '%s': %w", gitBaseURL, repoPath, err) + } + + return gitURL, nil +} diff --git a/internal/api/controller/repo/wire.go b/internal/api/controller/repo/wire.go index 52c8e98b1..84c3ad399 100644 --- a/internal/api/controller/repo/wire.go +++ b/internal/api/controller/repo/wire.go @@ -21,5 +21,6 @@ var WireSet = wire.NewSet( func ProvideController(config *types.Config, repoCheck check.Repo, authorizer authz.Authorizer, spaceStore store.SpaceStore, repoStore store.RepoStore, saStore store.ServiceAccountStore, rpcClient gitrpc.Interface) *Controller { - return NewController(config.Git.DefaultBranch, repoCheck, authorizer, spaceStore, repoStore, saStore, rpcClient) + return NewController(config.Git.DefaultBranch, config.Git.BaseURL, + repoCheck, authorizer, spaceStore, repoStore, saStore, rpcClient) } diff --git a/internal/api/controller/space/controller.go b/internal/api/controller/space/controller.go index b68047e84..7ab1e7fc2 100644 --- a/internal/api/controller/space/controller.go +++ b/internal/api/controller/space/controller.go @@ -11,6 +11,7 @@ import ( ) type Controller struct { + gitBaseURL string spaceCheck check.Space authorizer authz.Authorizer spaceStore store.SpaceStore @@ -18,9 +19,10 @@ type Controller struct { saStore store.ServiceAccountStore } -func NewController(spaceCheck check.Space, authorizer authz.Authorizer, spaceStore store.SpaceStore, +func NewController(gitBaseURL string, spaceCheck check.Space, authorizer authz.Authorizer, spaceStore store.SpaceStore, repoStore store.RepoStore, saStore store.ServiceAccountStore) *Controller { return &Controller{ + gitBaseURL: gitBaseURL, spaceCheck: spaceCheck, authorizer: authorizer, spaceStore: spaceStore, diff --git a/internal/api/controller/space/list_repositories.go b/internal/api/controller/space/list_repositories.go index 01f01ccf1..e4d9e1cca 100644 --- a/internal/api/controller/space/list_repositories.go +++ b/internal/api/controller/space/list_repositories.go @@ -9,6 +9,7 @@ import ( "fmt" apiauth "github.com/harness/gitness/internal/api/auth" + "github.com/harness/gitness/internal/api/controller/repo" "github.com/harness/gitness/internal/auth" "github.com/harness/gitness/types" "github.com/harness/gitness/types/enum" @@ -38,6 +39,13 @@ func (c *Controller) ListRepositories(ctx context.Context, session *auth.Session return nil, 0, fmt.Errorf("failed to list child repos: %w", err) } + for _, r := range repos { + r.GitURL, err = repo.GenerateRepoGitURL(c.gitBaseURL, r.Path) + if err != nil { + return nil, 0, err + } + } + /* * TODO: needs access control? Might want to avoid that (makes paging and performance hard) */ diff --git a/internal/api/controller/space/wire.go b/internal/api/controller/space/wire.go index 52c195f32..a44ffd4cd 100644 --- a/internal/api/controller/space/wire.go +++ b/internal/api/controller/space/wire.go @@ -8,15 +8,16 @@ import ( "github.com/google/wire" "github.com/harness/gitness/internal/auth/authz" "github.com/harness/gitness/internal/store" + "github.com/harness/gitness/types" "github.com/harness/gitness/types/check" ) // WireSet provides a wire set for this package. var WireSet = wire.NewSet( - NewController, + ProvideController, ) -func ProvideController(spaceCheck check.Space, authorizer authz.Authorizer, spaceStore store.SpaceStore, - repoStore store.RepoStore, saStore store.ServiceAccountStore) *Controller { - return NewController(spaceCheck, authorizer, spaceStore, repoStore, saStore) +func ProvideController(config *types.Config, spaceCheck check.Space, authorizer authz.Authorizer, + spaceStore store.SpaceStore, repoStore store.RepoStore, saStore store.ServiceAccountStore) *Controller { + return NewController(config.Git.BaseURL, spaceCheck, authorizer, spaceStore, repoStore, saStore) } diff --git a/internal/api/handler/repo/find.go b/internal/api/handler/repo/find.go index 0f9577483..407443203 100644 --- a/internal/api/handler/repo/find.go +++ b/internal/api/handler/repo/find.go @@ -6,10 +6,6 @@ package repo import ( "net/http" - "net/url" - "strings" - - "github.com/harness/gitness/types" "github.com/harness/gitness/internal/api/controller/repo" "github.com/harness/gitness/internal/api/render" @@ -17,7 +13,7 @@ import ( ) // HandleFind writes json-encoded repository information to the http response body. -func HandleFind(repoCtrl *repo.Controller, config *types.Config) http.HandlerFunc { +func HandleFind(repoCtrl *repo.Controller) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() session, _ := request.AuthSessionFrom(ctx) @@ -27,31 +23,12 @@ func HandleFind(repoCtrl *repo.Controller, config *types.Config) http.HandlerFun return } - repo, err := repoCtrl.Find(ctx, session, repoRef, config) + repo, err := repoCtrl.Find(ctx, session, repoRef) if err != nil { render.TranslatedUserError(w, err) return } - parse, err := url.Parse(repo.URL) - if err != nil { - render.TranslatedUserError(w, err) - return - } - - if parse.Host == "" { - parse.Host = r.Host - } - - if parse.Scheme == "" { - parse.Scheme = "http" - if !strings.Contains(parse.Host, "localhost") { - parse.Scheme = "https" - } - } - - repo.URL = parse.String() - render.JSON(w, http.StatusOK, repo) } } diff --git a/internal/router/api.go b/internal/router/api.go index f216f0e61..60e18b82c 100644 --- a/internal/router/api.go +++ b/internal/router/api.go @@ -78,7 +78,7 @@ func NewAPIHandler( r.Use(middlewareauthn.Attempt(authenticator)) r.Route("/v1", func(r chi.Router) { - setupRoutesV1(r, repoCtrl, spaceCtrl, saCtrl, userCtrl, config) + setupRoutesV1(r, repoCtrl, spaceCtrl, saCtrl, userCtrl) }) // wrap router in terminatedPath encoder. @@ -99,9 +99,9 @@ func corsHandler(config *types.Config) func(http.Handler) http.Handler { } func setupRoutesV1(r chi.Router, repoCtrl *repo.Controller, spaceCtrl *space.Controller, - saCtrl *serviceaccount.Controller, userCtrl *user.Controller, config *types.Config) { + saCtrl *serviceaccount.Controller, userCtrl *user.Controller) { setupSpaces(r, spaceCtrl) - setupRepos(r, repoCtrl, config) + setupRepos(r, repoCtrl) setupUsers(r, userCtrl) setupServiceAccounts(r, saCtrl) setupAdmin(r, userCtrl) @@ -140,13 +140,13 @@ func setupSpaces(r chi.Router, spaceCtrl *space.Controller) { }) } -func setupRepos(r chi.Router, repoCtrl *repo.Controller, config *types.Config) { +func setupRepos(r chi.Router, repoCtrl *repo.Controller) { r.Route("/repos", func(r chi.Router) { // Create takes path and parentId via body, not uri r.Post("/", handlerrepo.HandleCreate(repoCtrl)) r.Route(fmt.Sprintf("/{%s}", request.PathParamRepoRef), func(r chi.Router) { // repo level operations - r.Get("/", handlerrepo.HandleFind(repoCtrl, config)) + r.Get("/", handlerrepo.HandleFind(repoCtrl)) r.Put("/", handlerrepo.HandleUpdate(repoCtrl)) r.Delete("/", handlerrepo.HandleDelete(repoCtrl)) diff --git a/types/config.go b/types/config.go index 6331ff926..f40693249 100644 --- a/types/config.go +++ b/types/config.go @@ -13,7 +13,7 @@ type Config struct { // Git defines the git configuration parameters Git struct { - BaseURL string `envconfig:"GITNESS_GIT_BASE_URL"` // clone url + BaseURL string `envconfig:"GITNESS_GIT_BASE_URL" default:"http://localhost:3000"` // clone url Root string `envconfig:"GITNESS_GIT_ROOT"` DefaultBranch string `envconfig:"GITNESS_GIT_DEFAULTBRANCH" default:"main"` } diff --git a/types/repo.go b/types/repo.go index 5dfd2c322..b98c10ffe 100644 --- a/types/repo.go +++ b/types/repo.go @@ -33,7 +33,7 @@ type Repository struct { NumOpenPulls int `db:"repo_numOpenPulls" json:"numOpenPulls"` // git urls - URL string `db:"-" json:"url"` + GitURL string `db:"-" json:"gitUrl"` } // RepoFilter stores repo query parameters.