Skip to content

Commit

Permalink
Merge branch 'main' into feat/otel-tracing
Browse files Browse the repository at this point in the history
  • Loading branch information
KellyMerrick authored Sep 6, 2024
2 parents 938fe6b + b998ec1 commit e945cd8
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 10 deletions.
3 changes: 3 additions & 0 deletions api/oi_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func GetOpenIDConfig(c *gin.Context) {
"iat",
"iss",
"aud",
"branch",
"build_number",
"build_id",
"repo",
Expand All @@ -54,6 +55,8 @@ func GetOpenIDConfig(c *gin.Context) {
"actor_scm_id",
"commands",
"image",
"image_name",
"image_tag",
"request",
"event",
"sha",
Expand Down
15 changes: 9 additions & 6 deletions api/types/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,21 @@ type OpenIDConfig struct {
// OpenIDClaims struct is an extension of the JWT standard claims. It
// includes information relevant to OIDC services.
type OpenIDClaims struct {
BuildNumber int `json:"build_number,omitempty"`
BuildID int64 `json:"build_id,omitempty"`
Actor string `json:"actor,omitempty"`
ActorSCMID string `json:"actor_scm_id,omitempty"`
Repo string `json:"repo,omitempty"`
TokenType string `json:"token_type,omitempty"`
Image string `json:"image,omitempty"`
Request string `json:"request,omitempty"`
Branch string `json:"branch,omitempty"`
BuildID int64 `json:"build_id,omitempty"`
BuildNumber int `json:"build_number,omitempty"`
Commands bool `json:"commands,omitempty"`
Event string `json:"event,omitempty"`
Image string `json:"image,omitempty"`
ImageName string `json:"image_name,omitempty"`
ImageTag string `json:"image_tag,omitempty"`
Ref string `json:"ref,omitempty"`
Repo string `json:"repo,omitempty"`
Request string `json:"request,omitempty"`
SHA string `json:"sha,omitempty"`
TokenType string `json:"token_type,omitempty"`
jwt.RegisteredClaims
}

Expand Down
32 changes: 29 additions & 3 deletions internal/token/mint.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"context"
"errors"
"fmt"
"strings"
"time"

"github.com/golang-jwt/jwt/v5"
Expand Down Expand Up @@ -120,7 +121,7 @@ func (tm *Manager) MintToken(mto *MintTokenOpts) (string, error) {

tk := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

//sign token with configured private signing key
// sign token with configured private signing key
token, err := tk.SignedString([]byte(tm.PrivateKeyHMAC))
if err != nil {
return "", fmt.Errorf("unable to sign token: %w", err)
Expand All @@ -134,6 +135,8 @@ func (tm *Manager) MintIDToken(ctx context.Context, mto *MintTokenOpts, db datab
// initialize claims struct
var claims = new(api.OpenIDClaims)

var err error

// validate provided claims
if len(mto.Repo) == 0 {
return "", errors.New("missing repo for ID token")
Expand All @@ -154,6 +157,7 @@ func (tm *Manager) MintIDToken(ctx context.Context, mto *MintTokenOpts, db datab
// set claims based on input
claims.Actor = mto.Build.GetSender()
claims.ActorSCMID = mto.Build.GetSenderSCMID()
claims.Branch = mto.Build.GetBranch()
claims.BuildNumber = mto.Build.GetNumber()
claims.BuildID = mto.Build.GetID()
claims.Repo = mto.Repo
Expand All @@ -164,6 +168,12 @@ func (tm *Manager) MintIDToken(ctx context.Context, mto *MintTokenOpts, db datab
claims.Audience = mto.Audience
claims.TokenType = mto.TokenType
claims.Image = mto.Image

claims.ImageName, claims.ImageTag, err = imageParse(mto.Image)
if err != nil {
return "", err
}

claims.Request = mto.Request
claims.Commands = mto.Commands

Expand All @@ -175,7 +185,7 @@ func (tm *Manager) MintIDToken(ctx context.Context, mto *MintTokenOpts, db datab
tk := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)

// verify key is active in the database before signing
_, err := db.GetActiveJWK(ctx, tm.RSAKeySet.KID)
_, err = db.GetActiveJWK(ctx, tm.RSAKeySet.KID)
if err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
return "", fmt.Errorf("unable to get active public key: %w", err)
Expand All @@ -191,7 +201,7 @@ func (tm *Manager) MintIDToken(ctx context.Context, mto *MintTokenOpts, db datab
// set KID header
tk.Header["kid"] = tm.RSAKeySet.KID

//sign token with configured private signing key
// sign token with configured private signing key
token, err := tk.SignedString(tm.RSAKeySet.PrivateKey)
if err != nil {
return "", fmt.Errorf("unable to sign token: %w", err)
Expand All @@ -201,3 +211,19 @@ func (tm *Manager) MintIDToken(ctx context.Context, mto *MintTokenOpts, db datab

return token, nil
}

// imageParse parses the given image string and returns the image name and tag.
// If no tag is provided in the image string, "latest" is used as the tag.
// If the image string is invalid, an error is returned.
func imageParse(image string) (string, string, error) {
parts := strings.Split(image, ":")

switch len(parts) {
case 1:
return image, "latest", nil
case 2:
return parts[0], parts[1], nil
default:
return "", "", fmt.Errorf("invalid image format: %s", image)
}
}
61 changes: 61 additions & 0 deletions internal/token/mint_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// SPDX-License-Identifier: Apache-2.0

package token

import "testing"

func Test_imageParse(t *testing.T) {
type args struct {
image string
}
tests := []struct {
name string
args args
wantName string
wantTag string
wantErr bool
}{
{
name: "image with tag",
args: args{
image: "alpine:1.20",
},
wantName: "alpine",
wantTag: "1.20",
wantErr: false,
},
{
name: "image without latest tag",
args: args{
image: "alpine:latest",
},
wantName: "alpine",
wantTag: "latest",
wantErr: false,
},
{
name: "image without tag",
args: args{
image: "alpine",
},
wantName: "alpine",
wantTag: "latest",
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1, err := imageParse(tt.args.image)
if (err != nil) != tt.wantErr {
t.Errorf("imageParse() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.wantName {
t.Errorf("imageParse() got = %v, wantName %v", got, tt.wantName)
}
if got1 != tt.wantTag {
t.Errorf("imageParse() got1 = %v, wantName %v", got1, tt.wantTag)
}
})
}
}
3 changes: 3 additions & 0 deletions mock/server/authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const (
"iat",
"iss",
"aud",
"branch",
"build_number",
"build_id",
"repo",
Expand All @@ -40,6 +41,8 @@ const (
"actor_scm_id",
"commands",
"image",
"image_name",
"image_tag",
"request"
],
"id_token_signing_alg_values_supported": [
Expand Down
2 changes: 2 additions & 0 deletions mock/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ func FakeHandler() http.Handler {
e.POST("/api/v1/users", addUser)
e.PUT("/api/v1/users/:user", updateUser)
e.DELETE("/api/v1/users/:user", removeUser)
e.GET("/api/v1/user", currentUser)
e.PUT("/api/v1/user", currentUser)

// mock endpoints for worker calls
e.GET("/api/v1/workers", getWorkers)
Expand Down
24 changes: 23 additions & 1 deletion mock/server/user.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: Apache-2.0

//nolint:dupl // ignore duplicate with user code
package server

import (
Expand All @@ -12,6 +11,7 @@ import (
"github.com/gin-gonic/gin"

api "github.com/go-vela/server/api/types"
"github.com/go-vela/server/router/middleware/auth"
"github.com/go-vela/types"
)

Expand Down Expand Up @@ -82,6 +82,28 @@ func getUser(c *gin.Context) {
c.JSON(http.StatusOK, body)
}

// currentUser returns mock JSON for a http GET and http PUT.
//
// Pass "invalid" to auth header to test receiving 401 response.
func currentUser(c *gin.Context) {
tkn, _ := auth.RetrieveAccessToken(c.Request)

if strings.Contains(tkn, "invalid") {
msg := "unauthorized"

c.AbortWithStatusJSON(http.StatusUnauthorized, types.Error{Message: &msg})

return
}

data := []byte(UserResp)

var body api.User
_ = json.Unmarshal(data, &body)

c.JSON(http.StatusOK, body)
}

// addUser returns mock JSON for a http POST.
func addUser(c *gin.Context) {
data := []byte(UserResp)
Expand Down

0 comments on commit e945cd8

Please sign in to comment.