-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
373 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package api | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
"net/url" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/gin-gonic/gin" | ||
"github.com/go-vela/server/api/types" | ||
"github.com/go-vela/server/internal" | ||
"github.com/go-vela/server/scm" | ||
"github.com/go-vela/server/util" | ||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
// swagger:operation GET /install install Install | ||
// | ||
// Start SCM app installation flow and redirect to the external SCM destination | ||
// | ||
// --- | ||
// produces: | ||
// - application/json | ||
// parameters: | ||
// - in: query | ||
// name: type | ||
// description: The type of installation flow, either 'cli' or 'web' | ||
// type: string | ||
// - in: query | ||
// name: port | ||
// description: The local server port used during 'cli' flow | ||
// type: string | ||
// - in: query | ||
// name: org_scm_id | ||
// description: The SCM org id | ||
// type: string | ||
// - in: query | ||
// name: repo_scm_id | ||
// description: The SCM repo id | ||
// type: string | ||
// responses: | ||
// '307': | ||
// description: Redirected for installation | ||
// '400': | ||
// description: Invalid request payload | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
// '401': | ||
// description: Unauthorized | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
// '503': | ||
// description: Service unavailable | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
|
||
// Install represents the API handler to | ||
// process an SCM app installation for Vela from | ||
// the API or UI. | ||
func Install(c *gin.Context) { | ||
// capture middleware values | ||
l := c.MustGet("logger").(*logrus.Entry) | ||
scm := scm.FromContext(c) | ||
|
||
l.Debug("redirecting to SCM to complete app flow installation") | ||
|
||
orgSCMID, err := strconv.Atoi(util.FormParameter(c, "org_scm_id")) | ||
if err != nil { | ||
retErr := fmt.Errorf("unable to parse org_scm_id to integer: %v", err) | ||
|
||
util.HandleError(c, http.StatusBadRequest, retErr) | ||
|
||
return | ||
} | ||
|
||
repoSCMID, err := strconv.Atoi(util.FormParameter(c, "repo_scm_id")) | ||
if err != nil { | ||
retErr := fmt.Errorf("unable to parse repo_scm_id to integer: %v", err) | ||
|
||
util.HandleError(c, http.StatusBadRequest, retErr) | ||
|
||
return | ||
} | ||
|
||
// type cannot be empty | ||
t := util.FormParameter(c, "type") | ||
if len(t) == 0 { | ||
retErr := errors.New("no type query provided") | ||
|
||
util.HandleError(c, http.StatusBadRequest, retErr) | ||
|
||
return | ||
} | ||
|
||
// port can be empty when using web flow | ||
p := util.FormParameter(c, "port") | ||
|
||
// capture query params | ||
ri := &types.RepoInstall{ | ||
Type: t, | ||
Port: p, | ||
OrgSCMID: int64(orgSCMID), | ||
RepoSCMID: int64(repoSCMID), | ||
} | ||
|
||
// construct the repo installation url | ||
redirectURL, err := scm.GetRepoInstallURL(c.Request.Context(), ri) | ||
if err != nil { | ||
l.Errorf("unable to get repo install url: %v", err) | ||
|
||
return | ||
} | ||
|
||
c.Redirect(http.StatusTemporaryRedirect, redirectURL) | ||
} | ||
|
||
// GetAppInstallRedirectURL is a helper function to generate the redirect URL for completing an app installation flow. | ||
func GetAppInstallRedirectURL(ctx context.Context, l *logrus.Entry, m *internal.Metadata, q url.Values) (string, error) { | ||
// extract state that is passed along during the installation process | ||
pairs := strings.Split(q.Get("state"), ",") | ||
|
||
values := make(map[string]string) | ||
|
||
for _, pair := range pairs { | ||
parts := strings.SplitN(pair, "=", 2) | ||
if len(parts) == 2 { | ||
key := strings.TrimSpace(parts[0]) | ||
|
||
value := strings.TrimSpace(parts[1]) | ||
|
||
values[key] = value | ||
} | ||
} | ||
|
||
t, p := values["type"], values["port"] | ||
|
||
// default redirect location if a user ended up here | ||
// by providing an unsupported type | ||
r := fmt.Sprintf("%s/install", m.Vela.Address) | ||
|
||
switch t { | ||
// cli auth flow | ||
case "cli": | ||
r = fmt.Sprintf("http://127.0.0.1:%s", p) | ||
// web auth flow | ||
case "web": | ||
r = fmt.Sprintf("%s%s", m.Vela.WebAddress, m.Vela.WebOauthCallbackPath) | ||
} | ||
|
||
// append the code and state values | ||
r = fmt.Sprintf("%s?%s", r, q.Encode()) | ||
|
||
l.Debug("redirecting for final app installation flow") | ||
|
||
return r, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package repo | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/gin-gonic/gin" | ||
"github.com/sirupsen/logrus" | ||
|
||
"github.com/go-vela/server/internal" | ||
"github.com/go-vela/server/router/middleware/repo" | ||
"github.com/go-vela/server/router/middleware/user" | ||
"github.com/go-vela/server/scm" | ||
"github.com/go-vela/server/util" | ||
) | ||
|
||
// swagger:operation GET /api/v1/repos/{org}/{repo}/install/html_url repos GetInstallHTMLURL | ||
// | ||
// Repair a hook for a repository in Vela and the configured SCM | ||
// | ||
// --- | ||
// produces: | ||
// - application/json | ||
// parameters: | ||
// - in: path | ||
// name: org | ||
// description: Name of the organization | ||
// required: true | ||
// type: string | ||
// - in: path | ||
// name: repo | ||
// description: Name of the repository | ||
// required: true | ||
// type: string | ||
// security: | ||
// - ApiKeyAuth: [] | ||
// responses: | ||
// '200': | ||
// description: Successfully constructed the repo installation HTML URL | ||
// schema: | ||
// type: string | ||
// '401': | ||
// description: Unauthorized | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
// '404': | ||
// description: Not found | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
// '500': | ||
// description: Unexpected server error | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
|
||
// GetInstallHTMLURL represents the API handler to retrieve the | ||
// SCM installation HTML URL for a particular repo and Vela server. | ||
func GetInstallHTMLURL(c *gin.Context) { | ||
// capture middleware values | ||
m := c.MustGet("metadata").(*internal.Metadata) | ||
l := c.MustGet("logger").(*logrus.Entry) | ||
u := user.Retrieve(c) | ||
r := repo.Retrieve(c) | ||
scm := scm.FromContext(c) | ||
|
||
l.Debug("constructing repo install url") | ||
|
||
ri, err := scm.GetRepoInstallInfo(c.Request.Context(), u, r.GetOrg(), r.GetName()) | ||
if err != nil { | ||
retErr := fmt.Errorf("unable to get repo scm install info %s: %w", u.GetName(), err) | ||
|
||
util.HandleError(c, http.StatusInternalServerError, retErr) | ||
|
||
return | ||
} | ||
|
||
// todo: use url.values etc | ||
appInstallURL := fmt.Sprintf( | ||
"%s/install?org_scm_id=%d&repo_scm_id=%d", | ||
m.Vela.Address, | ||
ri.OrgSCMID, ri.RepoSCMID, | ||
) | ||
|
||
c.JSON(http.StatusOK, fmt.Sprintf("%s", appInstallURL)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
module github.com/go-vela/server | ||
|
||
go 1.23.1 | ||
go 1.23.2 | ||
|
||
replace github.com/go-vela/types => ../types | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.