-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* init commit * some renaming and comment fixing * tests and renaming things here and there, plus pull in types * update subject * integration test * pull in types and add event to subject * address lint review feedback * fix tests * more integration test fixes * bytes buffer for exponent * correct issuer and add commands claim * sender to actor * use lestrrat jwx lib for jwks * fixes * more fixes * use wrapper for swagger jwk set * address feedback * enhance: add build_id and actor_id to claims * enhance: complete adding build_id and actor_id to claims * enhance: complete adding build_id and actor_id to claims * fix: apply context to GenerateRSA * fix: add err check to ParseBool * enhance: audience validation * enhance: better audience validation * enhance: add query parameter input validation * tweak: order of operations, move sanitize lower * enhance: add scm user id to build obj * enhance: add GetUserID to scm interface * fix: apply missing scm id using scm client lookups * chore: verbose comment on fallback user fetch * chore: comment typo * enhance: use repo owner token in schedule processing * enhance: use repo owner token in restart build * enhance: change claims actor_id to actor_scm_id --------- Co-authored-by: davidvader <[email protected]>
- Loading branch information
Showing
62 changed files
with
2,919 additions
and
143 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package admin | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/gin-gonic/gin" | ||
"github.com/sirupsen/logrus" | ||
|
||
"github.com/go-vela/server/database" | ||
"github.com/go-vela/server/util" | ||
) | ||
|
||
// swagger:operation POST /api/v1/admin/rotate_oidc_keys admin AdminRotateOIDCKeys | ||
// | ||
// Rotate RSA Keys | ||
// | ||
// --- | ||
// produces: | ||
// - application/json | ||
// parameters: | ||
// security: | ||
// - ApiKeyAuth: [] | ||
// responses: | ||
// '200': | ||
// description: Successfully rotated OIDC provider keys | ||
// schema: | ||
// type: string | ||
// '500': | ||
// description: Error unable to rotate OIDC provider keys | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
|
||
// RotateOIDCKeys represents the API handler to | ||
// rotate RSA keys in OIDC provider service. | ||
func RotateOIDCKeys(c *gin.Context) { | ||
logrus.Info("Admin: rotating keys for OIDC provider") | ||
|
||
// capture middleware values | ||
ctx := c.Request.Context() | ||
|
||
err := database.FromContext(c).RotateKeys(ctx) | ||
if err != nil { | ||
retErr := fmt.Errorf("unable to rotate keys: %w", err) | ||
util.HandleError(c, http.StatusInternalServerError, retErr) | ||
|
||
return | ||
} | ||
|
||
c.JSON(http.StatusOK, "keys rotated successfully") | ||
} |
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,152 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package build | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
"strconv" | ||
"time" | ||
|
||
"github.com/gin-gonic/gin" | ||
"github.com/sirupsen/logrus" | ||
|
||
"github.com/go-vela/server/constants" | ||
"github.com/go-vela/server/internal/token" | ||
"github.com/go-vela/server/router/middleware/build" | ||
"github.com/go-vela/server/router/middleware/claims" | ||
"github.com/go-vela/server/util" | ||
"github.com/go-vela/types/library" | ||
) | ||
|
||
// swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/id_request_token builds GetIDRequestToken | ||
// | ||
// Get a Vela OIDC request token associated with a build | ||
// | ||
// --- | ||
// produces: | ||
// - application/json | ||
// parameters: | ||
// - in: path | ||
// name: repo | ||
// description: Name of the repo | ||
// required: true | ||
// type: string | ||
// - in: path | ||
// name: org | ||
// description: Name of the org | ||
// required: true | ||
// type: string | ||
// - in: path | ||
// name: build | ||
// description: Build number | ||
// required: true | ||
// type: integer | ||
// - in: query | ||
// name: image | ||
// description: Add image to token claims | ||
// type: string | ||
// - in: query | ||
// name: request | ||
// description: Add request input to token claims | ||
// type: string | ||
// - in: query | ||
// name: commands | ||
// description: Add commands input to token claims | ||
// type: boolean | ||
// security: | ||
// - ApiKeyAuth: [] | ||
// responses: | ||
// '200': | ||
// description: Successfully retrieved ID Request token | ||
// schema: | ||
// "$ref": "#/definitions/Token" | ||
// '400': | ||
// description: Bad request | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
// '401': | ||
// description: Unauthorized request | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
// '404': | ||
// description: Unable to find build | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
// '500': | ||
// description: Unable to generate ID request token | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
|
||
// GetIDRequestToken represents the API handler to generate and return an ID request token. | ||
func GetIDRequestToken(c *gin.Context) { | ||
// capture middleware values | ||
b := build.Retrieve(c) | ||
cl := claims.Retrieve(c) | ||
|
||
// update engine logger with API metadata | ||
// | ||
// https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields | ||
logrus.WithFields(logrus.Fields{ | ||
"build": b.GetNumber(), | ||
"org": b.GetRepo().GetOrg(), | ||
"repo": b.GetRepo().GetName(), | ||
"user": cl.Subject, | ||
}).Infof("generating ID request token for build %s/%d", b.GetRepo().GetFullName(), b.GetNumber()) | ||
|
||
image := c.Query("image") | ||
if len(image) == 0 { | ||
retErr := errors.New("no step 'image' provided in query parameters") | ||
|
||
util.HandleError(c, http.StatusBadRequest, retErr) | ||
|
||
return | ||
} | ||
|
||
request := c.Query("request") | ||
if len(request) == 0 { | ||
retErr := errors.New("no 'request' provided in query parameters") | ||
|
||
util.HandleError(c, http.StatusBadRequest, retErr) | ||
|
||
return | ||
} | ||
|
||
commands, err := strconv.ParseBool(c.Query("commands")) | ||
if err != nil { | ||
retErr := fmt.Errorf("unable to parse 'commands' query parameter as boolean %s: %w", c.Query("commands"), err) | ||
|
||
util.HandleError(c, http.StatusBadRequest, retErr) | ||
|
||
return | ||
} | ||
|
||
// retrieve token manager from context | ||
tm := c.MustGet("token-manager").(*token.Manager) | ||
|
||
exp := (time.Duration(b.GetRepo().GetTimeout()) * time.Minute) + tm.BuildTokenBufferDuration | ||
|
||
// set mint token options | ||
idmto := &token.MintTokenOpts{ | ||
Build: b, | ||
Repo: b.GetRepo().GetFullName(), | ||
TokenType: constants.IDRequestTokenType, | ||
TokenDuration: exp, | ||
Image: util.Sanitize(image), | ||
Request: util.Sanitize(request), | ||
Commands: commands, | ||
} | ||
|
||
// mint token | ||
idrt, err := tm.MintToken(idmto) | ||
if err != nil { | ||
retErr := fmt.Errorf("unable to generate ID request token: %w", err) | ||
|
||
util.HandleError(c, http.StatusInternalServerError, retErr) | ||
|
||
return | ||
} | ||
|
||
c.JSON(http.StatusOK, library.Token{Token: &idrt}) | ||
} |
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,138 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package build | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/gin-gonic/gin" | ||
"github.com/sirupsen/logrus" | ||
|
||
"github.com/go-vela/server/constants" | ||
"github.com/go-vela/server/database" | ||
"github.com/go-vela/server/internal/token" | ||
"github.com/go-vela/server/router/middleware/build" | ||
"github.com/go-vela/server/router/middleware/claims" | ||
"github.com/go-vela/server/util" | ||
"github.com/go-vela/types/library" | ||
) | ||
|
||
// swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/id_token builds GetIDToken | ||
// | ||
// Get a Vela OIDC token associated with a build | ||
// | ||
// --- | ||
// produces: | ||
// - application/json | ||
// parameters: | ||
// - in: path | ||
// name: repo | ||
// description: Name of the repo | ||
// required: true | ||
// type: string | ||
// - in: path | ||
// name: org | ||
// description: Name of the org | ||
// required: true | ||
// type: string | ||
// - in: path | ||
// name: build | ||
// description: Build number | ||
// required: true | ||
// type: integer | ||
// - in: query | ||
// name: audience | ||
// description: Add audience to token claims | ||
// type: array | ||
// items: | ||
// type: string | ||
// collectionFormat: multi | ||
// security: | ||
// - ApiKeyAuth: [] | ||
// responses: | ||
// '200': | ||
// description: Successfully retrieved ID token | ||
// schema: | ||
// "$ref": "#/definitions/Token" | ||
// '400': | ||
// description: Bad request | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
// '401': | ||
// description: Unauthorized request | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
// '404': | ||
// description: Unable to find build | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
// '500': | ||
// description: Unable to generate id token | ||
// schema: | ||
// "$ref": "#/definitions/Error" | ||
|
||
// GetIDToken represents the API handler to generate a id token. | ||
func GetIDToken(c *gin.Context) { | ||
// capture middleware values | ||
b := build.Retrieve(c) | ||
cl := claims.Retrieve(c) | ||
ctx := c.Request.Context() | ||
|
||
// update engine logger with API metadata | ||
// | ||
// https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields | ||
logrus.WithFields(logrus.Fields{ | ||
"build": b.GetNumber(), | ||
"org": b.GetRepo().GetOrg(), | ||
"repo": b.GetRepo().GetName(), | ||
"subject": cl.Subject, | ||
}).Infof("generating ID token for build %s/%d", b.GetRepo().GetFullName(), b.GetNumber()) | ||
|
||
// retrieve token manager from context | ||
tm := c.MustGet("token-manager").(*token.Manager) | ||
|
||
// set mint token options | ||
idmto := &token.MintTokenOpts{ | ||
Build: b, | ||
Repo: b.GetRepo().GetFullName(), | ||
TokenType: constants.IDTokenType, | ||
TokenDuration: tm.IDTokenDuration, | ||
Image: cl.Image, | ||
Request: cl.Request, | ||
Commands: cl.Commands, | ||
} | ||
|
||
// if audience is provided, include that in claims | ||
audience := []string{} | ||
|
||
if len(c.QueryArray("audience")) > 0 { | ||
for _, a := range c.QueryArray("audience") { | ||
if len(a) > 0 { | ||
audience = append(audience, util.Sanitize(a)) | ||
} | ||
} | ||
} | ||
|
||
if len(audience) == 0 { | ||
retErr := fmt.Errorf("unable to generate ID token: %s", "no audience provided") | ||
|
||
util.HandleError(c, http.StatusBadRequest, retErr) | ||
|
||
return | ||
} | ||
|
||
idmto.Audience = audience | ||
|
||
// mint token | ||
idt, err := tm.MintIDToken(ctx, idmto, database.FromContext(c)) | ||
if err != nil { | ||
retErr := fmt.Errorf("unable to generate ID token: %w", err) | ||
|
||
util.HandleError(c, http.StatusInternalServerError, retErr) | ||
|
||
return | ||
} | ||
|
||
c.JSON(http.StatusOK, library.Token{Token: &idt}) | ||
} |
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.