From 02fed7f99266f77577b269a1b31935c71a373c03 Mon Sep 17 00:00:00 2001 From: davidvader Date: Fri, 17 Mar 2023 16:47:54 -0500 Subject: [PATCH 01/16] feat: use validate-token endpoint in MustServer --- cmd/vela-worker/server.go | 1 + router/middleware/perm/perm.go | 72 ++++++++++++++++++++++++++++++---- router/middleware/server.go | 18 +++++++++ 3 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 router/middleware/server.go diff --git a/cmd/vela-worker/server.go b/cmd/vela-worker/server.go index cecd9210..38b26447 100644 --- a/cmd/vela-worker/server.go +++ b/cmd/vela-worker/server.go @@ -30,6 +30,7 @@ func (w *Worker) server() (http.Handler, *tls.Config) { // https://pkg.go.dev/github.com/go-vela/worker/router?tab=doc#Load _server := router.Load( middleware.RequestVersion, + middleware.ServerAddress(w.Config.Server.Address), middleware.Executors(w.Executors), middleware.Secret(w.Config.Server.Secret), middleware.Logger(logrus.StandardLogger(), time.RFC3339, true), diff --git a/router/middleware/perm/perm.go b/router/middleware/perm/perm.go index 135d452c..b2bb5fe8 100644 --- a/router/middleware/perm/perm.go +++ b/router/middleware/perm/perm.go @@ -7,10 +7,10 @@ package perm import ( "fmt" "net/http" - "strings" + "github.com/go-vela/sdk-go/vela" "github.com/go-vela/types" - "github.com/go-vela/worker/router/middleware/user" + "github.com/go-vela/worker/router/middleware/token" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" @@ -19,19 +19,75 @@ import ( // MustServer ensures the user is the vela server. func MustServer() gin.HandlerFunc { return func(c *gin.Context) { - u := user.Retrieve(c) + tkn, err := token.Retrieve(c.Request) + if err != nil { + msg := fmt.Sprintf("error parsing token") + + err := c.Error(fmt.Errorf(msg)) + if err != nil { + logrus.Error(err) + } + + c.AbortWithStatusJSON(http.StatusUnauthorized, err.Error()) - if strings.EqualFold(u.GetName(), "vela-server") { return } - msg := fmt.Sprintf("User %s is not a platform admin", u.GetName()) + addr, ok := c.MustGet("server-address").(string) + if !ok { + msg := fmt.Sprintf("error retrieving server address") + + err := c.Error(fmt.Errorf(msg)) + if err != nil { + logrus.Error(err) + } - err := c.Error(fmt.Errorf(msg)) + c.AbortWithStatusJSON(http.StatusInternalServerError, types.Error{Message: &msg}) + + return + } + + vela, err := vela.NewClient(addr, "", nil) if err != nil { - logrus.Error(err) + msg := fmt.Sprintf("error creating vela client") + + err := c.Error(fmt.Errorf(msg)) + if err != nil { + logrus.Error(err) + } + + c.AbortWithStatusJSON(http.StatusInternalServerError, types.Error{Message: &msg}) + + return } - c.AbortWithStatusJSON(http.StatusUnauthorized, types.Error{Message: &msg}) + vela.Authentication.SetTokenAuth(tkn) + + ok, _, err = vela.Authentication.ValidateToken() + if err != nil { + msg := fmt.Sprintf("error validating token") + + err := c.Error(fmt.Errorf(msg)) + if err != nil { + logrus.Error(err) + } + + c.AbortWithStatusJSON(http.StatusInternalServerError, types.Error{Message: &msg}) + + return + } + + if !ok { + msg := fmt.Sprintf("unable to validate token") + + err := c.Error(fmt.Errorf(msg)) + if err != nil { + logrus.Error(err) + } + + c.AbortWithStatusJSON(http.StatusUnauthorized, types.Error{Message: &msg}) + + return + } } } diff --git a/router/middleware/server.go b/router/middleware/server.go new file mode 100644 index 00000000..3c93dbfb --- /dev/null +++ b/router/middleware/server.go @@ -0,0 +1,18 @@ +// Copyright (c) 2023 Target Brands, Inc. All rights reserved. +// +// Use of this source code is governed by the LICENSE file in this repository. + +package middleware + +import ( + "github.com/gin-gonic/gin" +) + +// ServerAddress is a middleware function that attaches the +// server address to the context of every http.Request. +func ServerAddress(addr string) gin.HandlerFunc { + return func(c *gin.Context) { + c.Set("server-address", addr) + c.Next() + } +} From 1ba4511f013879f43a1cb3cef8e510d56945b9aa Mon Sep 17 00:00:00 2001 From: davidvader Date: Fri, 17 Mar 2023 17:13:00 -0500 Subject: [PATCH 02/16] fix: better error and removed ok check --- router/middleware/perm/perm.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/router/middleware/perm/perm.go b/router/middleware/perm/perm.go index b2bb5fe8..96c4fe45 100644 --- a/router/middleware/perm/perm.go +++ b/router/middleware/perm/perm.go @@ -63,9 +63,9 @@ func MustServer() gin.HandlerFunc { vela.Authentication.SetTokenAuth(tkn) - ok, _, err = vela.Authentication.ValidateToken() + _, err = vela.Authentication.ValidateToken() if err != nil { - msg := fmt.Sprintf("error validating token") + msg := fmt.Sprintf("error validating token: %s", err) err := c.Error(fmt.Errorf(msg)) if err != nil { From ee4dc7dd4b52ca20bd8a10c2bdcd68b55a1a2504 Mon Sep 17 00:00:00 2001 From: davidvader Date: Fri, 17 Mar 2023 17:13:34 -0500 Subject: [PATCH 03/16] fix: better error and removed ok check --- router/middleware/perm/perm.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/router/middleware/perm/perm.go b/router/middleware/perm/perm.go index 96c4fe45..2aa98fd6 100644 --- a/router/middleware/perm/perm.go +++ b/router/middleware/perm/perm.go @@ -76,18 +76,5 @@ func MustServer() gin.HandlerFunc { return } - - if !ok { - msg := fmt.Sprintf("unable to validate token") - - err := c.Error(fmt.Errorf(msg)) - if err != nil { - logrus.Error(err) - } - - c.AbortWithStatusJSON(http.StatusUnauthorized, types.Error{Message: &msg}) - - return - } } } From e81152993e3b35fea8c4dca3361c6d0ba966c584 Mon Sep 17 00:00:00 2001 From: davidvader Date: Thu, 23 Mar 2023 16:36:34 -0500 Subject: [PATCH 04/16] chore: bump types --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 9c85d09a..1db9bce8 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/gin-gonic/gin v1.9.0 github.com/go-vela/sdk-go v0.18.1 github.com/go-vela/server v0.18.1 - github.com/go-vela/types v0.18.1 + github.com/go-vela/types v0.18.2-0.20230321015315-6c723879639c github.com/google/go-cmp v0.5.9 github.com/joho/godotenv v1.5.1 github.com/opencontainers/image-spec v1.0.2 @@ -34,7 +34,7 @@ require ( github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect github.com/alicebob/miniredis/v2 v2.30.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/buildkite/yaml v0.0.0-20210326113714-4a3f40911396 // indirect + github.com/buildkite/yaml v0.0.0-20230306222819-0e4e032d4835 // indirect github.com/bytedance/sonic v1.8.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect diff --git a/go.sum b/go.sum index 2f666479..9ae0df04 100644 --- a/go.sum +++ b/go.sum @@ -68,8 +68,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bsm/ginkgo/v2 v2.5.0 h1:aOAnND1T40wEdAtkGSkvSICWeQ8L3UASX7YVCqQx+eQ= github.com/bsm/gomega v1.20.0 h1:JhAwLmtRzXFTx2AkALSLa8ijZafntmhSoU63Ok18Uq8= -github.com/buildkite/yaml v0.0.0-20210326113714-4a3f40911396 h1:qLN32md48xyTEqw6XEZMyNMre7njm0XXvDrea6NVwOM= -github.com/buildkite/yaml v0.0.0-20210326113714-4a3f40911396/go.mod h1:AV5wtJnn1/CRaRGlJ8xspkMWfKXV0/pkJVgGleTIrfk= +github.com/buildkite/yaml v0.0.0-20230306222819-0e4e032d4835 h1:Zfkih+Opdv9y5AOob+8iMsaMYnans+Ozrkb8wiPHbj0= +github.com/buildkite/yaml v0.0.0-20230306222819-0e4e032d4835/go.mod h1:AV5wtJnn1/CRaRGlJ8xspkMWfKXV0/pkJVgGleTIrfk= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA= github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= @@ -160,8 +160,8 @@ github.com/go-vela/sdk-go v0.18.1 h1:qsm8XWjr9btNDL8c58JC93sstRUybL/TklWgeeft860 github.com/go-vela/sdk-go v0.18.1/go.mod h1:QmfXBAdJ9prgE78TK13XJI8YjvGZA5hc+h79CbvgYGU= github.com/go-vela/server v0.18.1 h1:INd+nwLh0c+WA+8diIh4scLkByGBGZHiyVd5doLSolQ= github.com/go-vela/server v0.18.1/go.mod h1:WyJEXyJYYASfqN9PDuHqlBTbhsSRIzOn1E7tM2phZMA= -github.com/go-vela/types v0.18.1 h1:V/luHLnCEaJhD1m9PZCZicIasg8Op6MCK+utkz+gQiU= -github.com/go-vela/types v0.18.1/go.mod h1:6MzMhLaXKSZ9wiJveieqnBd2+4ZMS7yv7+POGSITyS8= +github.com/go-vela/types v0.18.2-0.20230321015315-6c723879639c h1:lnCL1knUGvgZQG4YBHSs/CZnxNBfqFUBlGhyq9LO9uk= +github.com/go-vela/types v0.18.2-0.20230321015315-6c723879639c/go.mod h1:6MzMhLaXKSZ9wiJveieqnBd2+4ZMS7yv7+POGSITyS8= github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA= github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= From 25c23957d502bc8573728e97437078f66383512d Mon Sep 17 00:00:00 2001 From: davidvader Date: Thu, 23 Mar 2023 17:29:14 -0500 Subject: [PATCH 05/16] feat: use refresh auth endpoint --- cmd/vela-worker/register.go | 10 ++++++++++ go.mod | 2 +- go.sum | 6 ++---- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/cmd/vela-worker/register.go b/cmd/vela-worker/register.go index 5de52721..6c95a29c 100644 --- a/cmd/vela-worker/register.go +++ b/cmd/vela-worker/register.go @@ -39,6 +39,16 @@ func (w *Worker) checkIn(config *library.Worker) error { return fmt.Errorf("unable to update worker %s on the server: %w", config.GetHostname(), err) } + // refresh the worker auth token + logrus.Infof("refreshing worker auth %s with the server", config.GetHostname()) + + tkn, _, err := w.VelaClient.Worker.RefreshAuth(config.GetHostname()) + if err != nil { + return fmt.Errorf("unable to refresh worker auth %s with the server: %w", config.GetHostname(), err) + } + + w.VelaClient.Authentication.SetTokenAuth(tkn.GetToken()) + return nil } diff --git a/go.mod b/go.mod index 1db9bce8..8e99a9d2 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/docker/go-units v0.5.0 github.com/gin-gonic/gin v1.9.0 github.com/go-vela/sdk-go v0.18.1 - github.com/go-vela/server v0.18.1 + github.com/go-vela/server v0.18.2-0.20230323213747-5ffbe819aa29 github.com/go-vela/types v0.18.2-0.20230321015315-6c723879639c github.com/google/go-cmp v0.5.9 github.com/joho/godotenv v1.5.1 diff --git a/go.sum b/go.sum index 9ae0df04..1ec894c1 100644 --- a/go.sum +++ b/go.sum @@ -156,10 +156,8 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-vela/sdk-go v0.18.1 h1:qsm8XWjr9btNDL8c58JC93sstRUybL/TklWgeeft860= -github.com/go-vela/sdk-go v0.18.1/go.mod h1:QmfXBAdJ9prgE78TK13XJI8YjvGZA5hc+h79CbvgYGU= -github.com/go-vela/server v0.18.1 h1:INd+nwLh0c+WA+8diIh4scLkByGBGZHiyVd5doLSolQ= -github.com/go-vela/server v0.18.1/go.mod h1:WyJEXyJYYASfqN9PDuHqlBTbhsSRIzOn1E7tM2phZMA= +github.com/go-vela/server v0.18.2-0.20230323213747-5ffbe819aa29 h1:DSbHMwxvI65vXAumZ1V9o82Q8W3J7Cce+grG8aqPPEw= +github.com/go-vela/server v0.18.2-0.20230323213747-5ffbe819aa29/go.mod h1:b+7XeGHO4ynIinY9mpWb6ye9psdwHpsAqMWy5oC+zJ0= github.com/go-vela/types v0.18.2-0.20230321015315-6c723879639c h1:lnCL1knUGvgZQG4YBHSs/CZnxNBfqFUBlGhyq9LO9uk= github.com/go-vela/types v0.18.2-0.20230321015315-6c723879639c/go.mod h1:6MzMhLaXKSZ9wiJveieqnBd2+4ZMS7yv7+POGSITyS8= github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA= From 1495e44938f81138f13f44a94ade8b19509870c4 Mon Sep 17 00:00:00 2001 From: davidvader Date: Fri, 24 Mar 2023 10:28:30 -0500 Subject: [PATCH 06/16] chore: remove user middleware in favor of MustServer token validation --- router/middleware/perm/perm.go | 8 +- router/middleware/perm/perm_test.go | 145 +++++++++++----------- router/middleware/user/context.go | 39 ------ router/middleware/user/context_test.go | 90 -------------- router/middleware/user/doc.go | 12 -- router/middleware/user/user.go | 44 ------- router/middleware/user/user_test.go | 162 ------------------------- router/router.go | 3 +- 8 files changed, 73 insertions(+), 430 deletions(-) delete mode 100644 router/middleware/user/context.go delete mode 100644 router/middleware/user/context_test.go delete mode 100644 router/middleware/user/doc.go delete mode 100644 router/middleware/user/user.go delete mode 100644 router/middleware/user/user_test.go diff --git a/router/middleware/perm/perm.go b/router/middleware/perm/perm.go index 2aa98fd6..bdc20302 100644 --- a/router/middleware/perm/perm.go +++ b/router/middleware/perm/perm.go @@ -16,12 +16,12 @@ import ( "github.com/sirupsen/logrus" ) -// MustServer ensures the user is the vela server. +// MustServer ensures the caller is the vela server. func MustServer() gin.HandlerFunc { return func(c *gin.Context) { tkn, err := token.Retrieve(c.Request) if err != nil { - msg := fmt.Sprintf("error parsing token") + msg := fmt.Sprintf("error parsing token: %s", err) err := c.Error(fmt.Errorf(msg)) if err != nil { @@ -35,7 +35,7 @@ func MustServer() gin.HandlerFunc { addr, ok := c.MustGet("server-address").(string) if !ok { - msg := fmt.Sprintf("error retrieving server address") + msg := "error retrieving server address" err := c.Error(fmt.Errorf(msg)) if err != nil { @@ -49,7 +49,7 @@ func MustServer() gin.HandlerFunc { vela, err := vela.NewClient(addr, "", nil) if err != nil { - msg := fmt.Sprintf("error creating vela client") + msg := fmt.Sprintf("error creating vela client: %s", err) err := c.Error(fmt.Errorf(msg)) if err != nil { diff --git a/router/middleware/perm/perm_test.go b/router/middleware/perm/perm_test.go index 64eb967c..326ecac3 100644 --- a/router/middleware/perm/perm_test.go +++ b/router/middleware/perm/perm_test.go @@ -5,90 +5,81 @@ package perm import ( - "fmt" - "net/http" - "net/http/httptest" "testing" - - "github.com/go-vela/worker/router/middleware/user" - - "github.com/go-vela/types/library" - - "github.com/gin-gonic/gin" ) func TestPerm_MustServer_success(t *testing.T) { // setup types - secret := "superSecret" - - u := new(library.User) - u.SetID(1) - u.SetName("vela-server") - u.SetToken("bar") - u.SetHash("baz") - u.SetAdmin(true) - - // setup context - gin.SetMode(gin.TestMode) - - resp := httptest.NewRecorder() - context, engine := gin.CreateTestContext(resp) - context.Request, _ = http.NewRequest(http.MethodGet, "/server/users", nil) - context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) - - // setup vela mock server - engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) - engine.Use(user.Establish()) - engine.Use(MustServer()) - engine.GET("/server/users", func(c *gin.Context) { - c.Status(http.StatusOK) - }) - - s1 := httptest.NewServer(engine) - defer s1.Close() - - // run test - engine.ServeHTTP(context.Writer, context.Request) - - if resp.Code != http.StatusOK { - t.Errorf("MustServer returned %v, want %v", resp.Code, http.StatusOK) - } + // secret := "superSecret" + + // u := new(library.User) + // u.SetID(1) + // u.SetName("vela-server") + // u.SetToken("bar") + // u.SetHash("baz") + // u.SetAdmin(true) + + // // setup context + // gin.SetMode(gin.TestMode) + + // resp := httptest.NewRecorder() + // context, engine := gin.CreateTestContext(resp) + // context.Request, _ = http.NewRequest(http.MethodGet, "/server/users", nil) + // context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) + + // // setup vela mock server + // engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) + // // engine.Use(user.Establish()) + // engine.Use(MustServer()) + // engine.GET("/server/users", func(c *gin.Context) { + // c.Status(http.StatusOK) + // }) + + // s1 := httptest.NewServer(engine) + // defer s1.Close() + + // // run test + // engine.ServeHTTP(context.Writer, context.Request) + + // if resp.Code != http.StatusOK { + // t.Errorf("MustServer returned %v, want %v", resp.Code, http.StatusOK) + // } } func TestPerm_MustServer_failure(t *testing.T) { // setup types - secret := "foo" - - u := new(library.User) - u.SetID(1) - u.SetName("not-vela-server") - u.SetToken("bar") - u.SetHash("baz") - u.SetAdmin(true) - - // setup context - gin.SetMode(gin.TestMode) - - resp := httptest.NewRecorder() - context, engine := gin.CreateTestContext(resp) - context.Request, _ = http.NewRequest(http.MethodGet, "/server/users", nil) - context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) - - // setup vela mock server - engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) - engine.Use(func(c *gin.Context) { c.Set("user", u) }) - engine.Use(MustServer()) - engine.GET("/server/users", func(c *gin.Context) { - c.Status(http.StatusOK) - }) - - s1 := httptest.NewServer(engine) - defer s1.Close() - - // run test - engine.ServeHTTP(context.Writer, context.Request) - - if resp.Code != http.StatusUnauthorized { - t.Errorf("MustServer returned %v, want %v", resp.Code, http.StatusUnauthorized) - } + // secret := "foo" + + // u := new(library.User) + // u.SetID(1) + // u.SetName("not-vela-server") + // u.SetToken("bar") + // u.SetHash("baz") + // u.SetAdmin(true) + + // // setup context + // gin.SetMode(gin.TestMode) + + // resp := httptest.NewRecorder() + // context, engine := gin.CreateTestContext(resp) + // context.Request, _ = http.NewRequest(http.MethodGet, "/server/users", nil) + // context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) + + // // setup vela mock server + // engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) + // engine.Use(func(c *gin.Context) { c.Set("user", u) }) + // engine.Use(MustServer()) + // engine.GET("/server/users", func(c *gin.Context) { + // c.Status(http.StatusOK) + // }) + + // s1 := httptest.NewServer(engine) + // defer s1.Close() + + // // run test + // engine.ServeHTTP(context.Writer, context.Request) + + // if resp.Code != http.StatusUnauthorized { + // t.Errorf("MustServer returned %v, want %v", resp.Code, http.StatusUnauthorized) + // } } diff --git a/router/middleware/user/context.go b/router/middleware/user/context.go deleted file mode 100644 index 944a1f3e..00000000 --- a/router/middleware/user/context.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2022 Target Brands, Inc. All rights reserved. -// -// Use of this source code is governed by the LICENSE file in this repository. - -package user - -import ( - "context" - - "github.com/go-vela/types/library" -) - -const key = "user" - -// Setter defines a context that enables setting values. -type Setter interface { - Set(string, interface{}) -} - -// FromContext returns the User associated with this context. -func FromContext(c context.Context) *library.User { - value := c.Value(key) - if value == nil { - return nil - } - - u, ok := value.(*library.User) - if !ok { - return nil - } - - return u -} - -// ToContext adds the User to this context if it supports -// the Setter interface. -func ToContext(c Setter, u *library.User) { - c.Set(key, u) -} diff --git a/router/middleware/user/context_test.go b/router/middleware/user/context_test.go deleted file mode 100644 index 6cfe188a..00000000 --- a/router/middleware/user/context_test.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 2022 Target Brands, Inc. All rights reserved. -// -// Use of this source code is governed by the LICENSE file in this repository. - -package user - -import ( - "testing" - - "github.com/go-vela/types/library" - - "github.com/gin-gonic/gin" -) - -func TestUser_FromContext(t *testing.T) { - // setup types - uID := int64(1) - want := &library.User{ID: &uID} - - // setup context - gin.SetMode(gin.TestMode) - context, _ := gin.CreateTestContext(nil) - context.Set(key, want) - - // run test - got := FromContext(context) - - if got != want { - t.Errorf("FromContext is %v, want %v", got, want) - } -} - -func TestUser_FromContext_Bad(t *testing.T) { - // setup context - gin.SetMode(gin.TestMode) - context, _ := gin.CreateTestContext(nil) - context.Set(key, nil) - - // run test - got := FromContext(context) - - if got != nil { - t.Errorf("FromContext is %v, want nil", got) - } -} - -func TestUser_FromContext_WrongType(t *testing.T) { - // setup context - gin.SetMode(gin.TestMode) - context, _ := gin.CreateTestContext(nil) - context.Set(key, 1) - - // run test - got := FromContext(context) - - if got != nil { - t.Errorf("FromContext is %v, want nil", got) - } -} - -func TestUser_FromContext_Empty(t *testing.T) { - // setup context - gin.SetMode(gin.TestMode) - context, _ := gin.CreateTestContext(nil) - - // run test - got := FromContext(context) - - if got != nil { - t.Errorf("FromContext is %v, want nil", got) - } -} - -func TestUser_ToContext(t *testing.T) { - // setup types - uID := int64(1) - want := &library.User{ID: &uID} - - // setup context - gin.SetMode(gin.TestMode) - context, _ := gin.CreateTestContext(nil) - ToContext(context, want) - - // run test - got := context.Value(key) - - if got != want { - t.Errorf("ToContext is %v, want %v", got, want) - } -} diff --git a/router/middleware/user/doc.go b/router/middleware/user/doc.go deleted file mode 100644 index 7ba0a485..00000000 --- a/router/middleware/user/doc.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2022 Target Brands, Inc. All rights reserved. -// -// Use of this source code is governed by the LICENSE file in this repository. - -// Package user provides the ability for inserting -// Vela user resources into or extracting Vela user -// resources from the middleware chain for the API. -// -// Usage: -// -// import "github.com/go-vela/worker/router/middleware/user" -package user diff --git a/router/middleware/user/user.go b/router/middleware/user/user.go deleted file mode 100644 index 817aa0e9..00000000 --- a/router/middleware/user/user.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2022 Target Brands, Inc. All rights reserved. -// -// Use of this source code is governed by the LICENSE file in this repository. - -package user - -import ( - "net/http" - "strings" - - "github.com/go-vela/worker/router/middleware/token" - - "github.com/go-vela/types/library" - - "github.com/gin-gonic/gin" -) - -// Retrieve gets the user in the given context. -func Retrieve(c *gin.Context) *library.User { - return FromContext(c) -} - -// Establish sets the user in the given context. -func Establish() gin.HandlerFunc { - return func(c *gin.Context) { - u := new(library.User) - - t, err := token.Retrieve(c.Request) - if err != nil { - c.AbortWithStatusJSON(http.StatusUnauthorized, err.Error()) - return - } - - secret := c.MustGet("secret").(string) - if strings.EqualFold(t, secret) { - u.SetName("vela-server") - u.SetActive(true) - u.SetAdmin(true) - } - - ToContext(c, u) - c.Next() - } -} diff --git a/router/middleware/user/user_test.go b/router/middleware/user/user_test.go deleted file mode 100644 index b4f8b52f..00000000 --- a/router/middleware/user/user_test.go +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) 2022 Target Brands, Inc. All rights reserved. -// -// Use of this source code is governed by the LICENSE file in this repository. - -package user - -import ( - "fmt" - "net/http" - "net/http/httptest" - "reflect" - "testing" - - "github.com/go-vela/types/library" - - "github.com/gin-gonic/gin" -) - -func TestUser_Retrieve(t *testing.T) { - // setup types - want := new(library.User) - want.SetID(1) - - // setup context - gin.SetMode(gin.TestMode) - - context, _ := gin.CreateTestContext(nil) - ToContext(context, want) - - // run test - got := Retrieve(context) - - if got != want { - t.Errorf("Retrieve is %v, want %v", got, want) - } -} - -func TestUser_Establish(t *testing.T) { - // setup types - secret := "superSecret" - got := new(library.User) - want := new(library.User) - want.SetName("vela-server") - want.SetActive(true) - want.SetAdmin(true) - - // setup context - gin.SetMode(gin.TestMode) - - resp := httptest.NewRecorder() - context, engine := gin.CreateTestContext(resp) - context.Request, _ = http.NewRequest(http.MethodGet, "/users/vela-server", nil) - context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) - - // setup vela mock server - engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) - engine.Use(Establish()) - engine.GET("/users/:user", func(c *gin.Context) { - got = Retrieve(c) - - c.Status(http.StatusOK) - }) - - s1 := httptest.NewServer(engine) - defer s1.Close() - - // run test - engine.ServeHTTP(context.Writer, context.Request) - - if resp.Code != http.StatusOK { - t.Errorf("Establish returned %v, want %v", resp.Code, http.StatusOK) - } - - if !reflect.DeepEqual(got, want) { - t.Errorf("Establish is %v, want %v", got, want) - } -} - -func TestUser_Establish_NoToken(t *testing.T) { - // setup context - gin.SetMode(gin.TestMode) - - resp := httptest.NewRecorder() - context, engine := gin.CreateTestContext(resp) - context.Request, _ = http.NewRequest(http.MethodGet, "/users/foo", nil) - - // setup mock server - engine.Use(Establish()) - - // run test - engine.ServeHTTP(context.Writer, context.Request) - - if resp.Code != http.StatusUnauthorized { - t.Errorf("Establish returned %v, want %v", resp.Code, http.StatusUnauthorized) - } -} - -func TestUser_Establish_SecretValid(t *testing.T) { - // setup types - secret := "superSecret" - - want := new(library.User) - want.SetName("vela-server") - want.SetActive(true) - want.SetAdmin(true) - - got := new(library.User) - - // setup context - gin.SetMode(gin.TestMode) - - resp := httptest.NewRecorder() - context, engine := gin.CreateTestContext(resp) - context.Request, _ = http.NewRequest(http.MethodGet, "/users/vela-server", nil) - context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) - - // setup vela mock server - engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) - engine.Use(Establish()) - engine.GET("/users/:user", func(c *gin.Context) { - got = Retrieve(c) - - c.Status(http.StatusOK) - }) - - s := httptest.NewServer(engine) - defer s.Close() - - // run test - engine.ServeHTTP(context.Writer, context.Request) - - if resp.Code != http.StatusOK { - t.Errorf("Establish returned %v, want %v", resp.Code, http.StatusOK) - } - - if !reflect.DeepEqual(got, want) { - t.Errorf("Establish is %v, want %v", got, want) - } -} - -func TestUser_Establish_NoAuthorizeUser(t *testing.T) { - // setup types - secret := "superSecret" - - // setup context - gin.SetMode(gin.TestMode) - - resp := httptest.NewRecorder() - context, engine := gin.CreateTestContext(resp) - context.Request, _ = http.NewRequest(http.MethodGet, "/users/foo?access_token=bar", nil) - - // setup vela mock server - engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) - engine.Use(Establish()) - - // run test - engine.ServeHTTP(context.Writer, context.Request) - - if resp.Code != http.StatusUnauthorized { - t.Errorf("Establish returned %v, want %v", resp.Code, http.StatusUnauthorized) - } -} diff --git a/router/router.go b/router/router.go index 222029df..14b3955c 100644 --- a/router/router.go +++ b/router/router.go @@ -31,7 +31,6 @@ import ( "github.com/go-vela/worker/api" "github.com/go-vela/worker/router/middleware" "github.com/go-vela/worker/router/middleware/perm" - "github.com/go-vela/worker/router/middleware/user" ) const ( @@ -95,7 +94,7 @@ func Load(options ...gin.HandlerFunc) *gin.Engine { // add a collection of endpoints for handling API related requests // // https://pkg.go.dev/github.com/gin-gonic/gin?tab=doc#RouterGroup.Group - baseAPI := r.Group(base, user.Establish(), perm.MustServer()) + baseAPI := r.Group(base, perm.MustServer()) { // add an endpoint for shutting down the worker // From c6fa06f91ab06246873ae33facb7e4668e59f62b Mon Sep 17 00:00:00 2001 From: davidvader Date: Fri, 24 Mar 2023 11:00:18 -0500 Subject: [PATCH 07/16] chore: remove worker.RefreshAuth in favor of separate branch --- cmd/vela-worker/register.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/cmd/vela-worker/register.go b/cmd/vela-worker/register.go index 6c95a29c..5de52721 100644 --- a/cmd/vela-worker/register.go +++ b/cmd/vela-worker/register.go @@ -39,16 +39,6 @@ func (w *Worker) checkIn(config *library.Worker) error { return fmt.Errorf("unable to update worker %s on the server: %w", config.GetHostname(), err) } - // refresh the worker auth token - logrus.Infof("refreshing worker auth %s with the server", config.GetHostname()) - - tkn, _, err := w.VelaClient.Worker.RefreshAuth(config.GetHostname()) - if err != nil { - return fmt.Errorf("unable to refresh worker auth %s with the server: %w", config.GetHostname(), err) - } - - w.VelaClient.Authentication.SetTokenAuth(tkn.GetToken()) - return nil } From 686e8a7dd5bc8d860432a5a625e538a79745d409 Mon Sep 17 00:00:00 2001 From: davidvader Date: Mon, 27 Mar 2023 09:20:49 -0500 Subject: [PATCH 08/16] chore: bump server --- go.mod | 2 +- go.sum | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8e99a9d2..097a0371 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/docker/go-units v0.5.0 github.com/gin-gonic/gin v1.9.0 github.com/go-vela/sdk-go v0.18.1 - github.com/go-vela/server v0.18.2-0.20230323213747-5ffbe819aa29 + github.com/go-vela/server v0.18.2-0.20230324155739-73f83fcfd004 github.com/go-vela/types v0.18.2-0.20230321015315-6c723879639c github.com/google/go-cmp v0.5.9 github.com/joho/godotenv v1.5.1 diff --git a/go.sum b/go.sum index 1ec894c1..dccb45d1 100644 --- a/go.sum +++ b/go.sum @@ -156,8 +156,10 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-vela/server v0.18.2-0.20230323213747-5ffbe819aa29 h1:DSbHMwxvI65vXAumZ1V9o82Q8W3J7Cce+grG8aqPPEw= -github.com/go-vela/server v0.18.2-0.20230323213747-5ffbe819aa29/go.mod h1:b+7XeGHO4ynIinY9mpWb6ye9psdwHpsAqMWy5oC+zJ0= +github.com/go-vela/sdk-go v0.18.1 h1:qsm8XWjr9btNDL8c58JC93sstRUybL/TklWgeeft860= +github.com/go-vela/sdk-go v0.18.1/go.mod h1:QmfXBAdJ9prgE78TK13XJI8YjvGZA5hc+h79CbvgYGU= +github.com/go-vela/server v0.18.2-0.20230324155739-73f83fcfd004 h1:yJis1sso5c0ZoeZLfZ/lYsjfxU7H9cYP/VJXssRxDa8= +github.com/go-vela/server v0.18.2-0.20230324155739-73f83fcfd004/go.mod h1:b+7XeGHO4ynIinY9mpWb6ye9psdwHpsAqMWy5oC+zJ0= github.com/go-vela/types v0.18.2-0.20230321015315-6c723879639c h1:lnCL1knUGvgZQG4YBHSs/CZnxNBfqFUBlGhyq9LO9uk= github.com/go-vela/types v0.18.2-0.20230321015315-6c723879639c/go.mod h1:6MzMhLaXKSZ9wiJveieqnBd2+4ZMS7yv7+POGSITyS8= github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA= From 9576d68597cd51372a7670c20c1eba191305f782 Mon Sep 17 00:00:00 2001 From: davidvader Date: Mon, 27 Mar 2023 09:21:16 -0500 Subject: [PATCH 09/16] chore: bump sdk-go --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 097a0371..cc15e3ba 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/docker/docker v20.10.23+incompatible github.com/docker/go-units v0.5.0 github.com/gin-gonic/gin v1.9.0 - github.com/go-vela/sdk-go v0.18.1 + github.com/go-vela/sdk-go v0.18.2-0.20230327141933-e8d38c73b1bb github.com/go-vela/server v0.18.2-0.20230324155739-73f83fcfd004 github.com/go-vela/types v0.18.2-0.20230321015315-6c723879639c github.com/google/go-cmp v0.5.9 diff --git a/go.sum b/go.sum index dccb45d1..41742c03 100644 --- a/go.sum +++ b/go.sum @@ -158,6 +158,8 @@ github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVL github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-vela/sdk-go v0.18.1 h1:qsm8XWjr9btNDL8c58JC93sstRUybL/TklWgeeft860= github.com/go-vela/sdk-go v0.18.1/go.mod h1:QmfXBAdJ9prgE78TK13XJI8YjvGZA5hc+h79CbvgYGU= +github.com/go-vela/sdk-go v0.18.2-0.20230327141933-e8d38c73b1bb h1:JXEolOu+HFktExoDFcGYIdWS9LfPAQnQMIB4Rm48WS0= +github.com/go-vela/sdk-go v0.18.2-0.20230327141933-e8d38c73b1bb/go.mod h1:N8qFPxB0RsHrSYr01GVwgOOowtSfhvjXtJ1cRBaeTc4= github.com/go-vela/server v0.18.2-0.20230324155739-73f83fcfd004 h1:yJis1sso5c0ZoeZLfZ/lYsjfxU7H9cYP/VJXssRxDa8= github.com/go-vela/server v0.18.2-0.20230324155739-73f83fcfd004/go.mod h1:b+7XeGHO4ynIinY9mpWb6ye9psdwHpsAqMWy5oC+zJ0= github.com/go-vela/types v0.18.2-0.20230321015315-6c723879639c h1:lnCL1knUGvgZQG4YBHSs/CZnxNBfqFUBlGhyq9LO9uk= From 98ac9aaeeddcba2684c104d284e9b7cc4bffb985 Mon Sep 17 00:00:00 2001 From: davidvader Date: Mon, 27 Mar 2023 09:21:52 -0500 Subject: [PATCH 10/16] chore: bump server --- go.sum | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.sum b/go.sum index 41742c03..6d05d5c5 100644 --- a/go.sum +++ b/go.sum @@ -156,8 +156,6 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-vela/sdk-go v0.18.1 h1:qsm8XWjr9btNDL8c58JC93sstRUybL/TklWgeeft860= -github.com/go-vela/sdk-go v0.18.1/go.mod h1:QmfXBAdJ9prgE78TK13XJI8YjvGZA5hc+h79CbvgYGU= github.com/go-vela/sdk-go v0.18.2-0.20230327141933-e8d38c73b1bb h1:JXEolOu+HFktExoDFcGYIdWS9LfPAQnQMIB4Rm48WS0= github.com/go-vela/sdk-go v0.18.2-0.20230327141933-e8d38c73b1bb/go.mod h1:N8qFPxB0RsHrSYr01GVwgOOowtSfhvjXtJ1cRBaeTc4= github.com/go-vela/server v0.18.2-0.20230324155739-73f83fcfd004 h1:yJis1sso5c0ZoeZLfZ/lYsjfxU7H9cYP/VJXssRxDa8= From fab0b73ad45957ce582e3a8fbe3a4a66b508c5f6 Mon Sep 17 00:00:00 2001 From: davidvader Date: Mon, 27 Mar 2023 12:18:34 -0500 Subject: [PATCH 11/16] wip: perm_test.go --- router/middleware/perm/perm_test.go | 58 ++++++++++++----------------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/router/middleware/perm/perm_test.go b/router/middleware/perm/perm_test.go index 326ecac3..22e91562 100644 --- a/router/middleware/perm/perm_test.go +++ b/router/middleware/perm/perm_test.go @@ -5,45 +5,33 @@ package perm import ( + "net/http" + "net/http/httptest" "testing" + + "github.com/gin-gonic/gin" ) func TestPerm_MustServer_success(t *testing.T) { - // setup types - // secret := "superSecret" - - // u := new(library.User) - // u.SetID(1) - // u.SetName("vela-server") - // u.SetToken("bar") - // u.SetHash("baz") - // u.SetAdmin(true) - - // // setup context - // gin.SetMode(gin.TestMode) - - // resp := httptest.NewRecorder() - // context, engine := gin.CreateTestContext(resp) - // context.Request, _ = http.NewRequest(http.MethodGet, "/server/users", nil) - // context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) - - // // setup vela mock server - // engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) - // // engine.Use(user.Establish()) - // engine.Use(MustServer()) - // engine.GET("/server/users", func(c *gin.Context) { - // c.Status(http.StatusOK) - // }) - - // s1 := httptest.NewServer(engine) - // defer s1.Close() - - // // run test - // engine.ServeHTTP(context.Writer, context.Request) - - // if resp.Code != http.StatusOK { - // t.Errorf("MustServer returned %v, want %v", resp.Code, http.StatusOK) - // } + // setup context + gin.SetMode(gin.TestMode) + resp := httptest.NewRecorder() + context, engine := gin.CreateTestContext(resp) + context.Request, _ = http.NewRequest(http.MethodGet, "/server/users", nil) + // setup vela mock server + engine.GET("/server/users", func(c *gin.Context) { + c.Status(http.StatusInternalServerError) + c.JSON(500, nil) + }) + s1 := httptest.NewServer(engine) + defer s1.Close() + + // run test + engine.ServeHTTP(context.Writer, context.Request) + + if resp.Code != http.StatusOK { + t.Errorf("MustServer returned %v, want %v", resp.Code, http.StatusOK) + } } func TestPerm_MustServer_failure(t *testing.T) { From 37e055bc4aba3bbf1a6b8f4d28fab76d769de9d9 Mon Sep 17 00:00:00 2001 From: davidvader Date: Mon, 27 Mar 2023 15:37:04 -0500 Subject: [PATCH 12/16] feat: MustServer tests --- router/middleware/perm/perm.go | 38 +++- router/middleware/perm/perm_test.go | 315 +++++++++++++++++++++++----- 2 files changed, 304 insertions(+), 49 deletions(-) diff --git a/router/middleware/perm/perm.go b/router/middleware/perm/perm.go index bdc20302..f8c51f66 100644 --- a/router/middleware/perm/perm.go +++ b/router/middleware/perm/perm.go @@ -7,6 +7,7 @@ package perm import ( "fmt" "net/http" + "strings" "github.com/go-vela/sdk-go/vela" "github.com/go-vela/types" @@ -19,6 +20,7 @@ import ( // MustServer ensures the caller is the vela server. func MustServer() gin.HandlerFunc { return func(c *gin.Context) { + // retrieve the callers token from the request headers tkn, err := token.Retrieve(c.Request) if err != nil { msg := fmt.Sprintf("error parsing token: %s", err) @@ -33,6 +35,7 @@ func MustServer() gin.HandlerFunc { return } + // retrieve the configured server address from the context addr, ok := c.MustGet("server-address").(string) if !ok { msg := "error retrieving server address" @@ -47,7 +50,8 @@ func MustServer() gin.HandlerFunc { return } - vela, err := vela.NewClient(addr, "", nil) + // create a temporary client to validate the incoming request + vela, err := vela.NewClient(addr, "vela-worker", nil) if err != nil { msg := fmt.Sprintf("error creating vela client: %s", err) @@ -61,9 +65,25 @@ func MustServer() gin.HandlerFunc { return } + // validate a token was provided + if strings.EqualFold(tkn, "") { + msg := "missing token" + + err := c.Error(fmt.Errorf(msg)) + if err != nil { + logrus.Error(err) + } + + c.AbortWithStatusJSON(http.StatusBadRequest, types.Error{Message: &msg}) + + return + } + + // set the token auth provided in the callers request header vela.Authentication.SetTokenAuth(tkn) - _, err = vela.Authentication.ValidateToken() + // validate the token with the configured vela server + resp, err := vela.Authentication.ValidateToken() if err != nil { msg := fmt.Sprintf("error validating token: %s", err) @@ -76,5 +96,19 @@ func MustServer() gin.HandlerFunc { return } + + // if ValidateToken returned anything other than 200 consider the token invalid + if resp.StatusCode != http.StatusOK { + msg := "unable to validate token" + + err := c.Error(fmt.Errorf(msg)) + if err != nil { + logrus.Error(err) + } + + c.AbortWithStatusJSON(http.StatusUnauthorized, types.Error{Message: &msg}) + + return + } } } diff --git a/router/middleware/perm/perm_test.go b/router/middleware/perm/perm_test.go index 22e91562..b1d4d6d3 100644 --- a/router/middleware/perm/perm_test.go +++ b/router/middleware/perm/perm_test.go @@ -5,6 +5,7 @@ package perm import ( + "fmt" "net/http" "net/http/httptest" "testing" @@ -12,62 +13,282 @@ import ( "github.com/gin-gonic/gin" ) -func TestPerm_MustServer_success(t *testing.T) { +func TestPerm_MustServer_ValidateToken200(t *testing.T) { + // setup types + secret := "superSecret" + // setup context gin.SetMode(gin.TestMode) - resp := httptest.NewRecorder() - context, engine := gin.CreateTestContext(resp) - context.Request, _ = http.NewRequest(http.MethodGet, "/server/users", nil) - // setup vela mock server - engine.GET("/server/users", func(c *gin.Context) { + + // setup mock worker router + workerResp := httptest.NewRecorder() + workerCtx, workerEngine := gin.CreateTestContext(workerResp) + + // fake request made to the worker router + workerCtx.Request, _ = http.NewRequest(http.MethodGet, "/build/cancel", nil) + workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) + + // setup mock server router + // the URL of the mock server router is injected into the mock worker router + serverResp := httptest.NewRecorder() + _, serverEngine := gin.CreateTestContext(serverResp) + + // mocked token validation endpoint used in MustServer + serverEngine.GET("/validate-token", func(c *gin.Context) { + // token is not expired and matches server token + c.Status(http.StatusOK) + }) + + serverMock := httptest.NewServer(serverEngine) + defer serverMock.Close() + + workerEngine.Use(func(c *gin.Context) { c.Set("server-address", serverMock.URL) }) + + // attach perm middleware that we are testing + workerEngine.Use(MustServer()) + workerEngine.GET("/build/cancel", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + workerMock := httptest.NewServer(workerEngine) + defer workerMock.Close() + + // run test + workerEngine.ServeHTTP(workerCtx.Writer, workerCtx.Request) + + if workerResp.Code != http.StatusOK { + t.Errorf("MustServer returned %v, want %v", workerResp.Code, http.StatusOK) + } +} + +func TestPerm_MustServer_ValidateToken401(t *testing.T) { + // setup types + secret := "superSecret" + + // setup context + gin.SetMode(gin.TestMode) + + // setup mock worker router + workerResp := httptest.NewRecorder() + workerCtx, workerEngine := gin.CreateTestContext(workerResp) + + // fake request made to the worker router + workerCtx.Request, _ = http.NewRequest(http.MethodGet, "/build/cancel", nil) + workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) + + // setup mock server router + // the URL of the mock server router is injected into the mock worker router + serverResp := httptest.NewRecorder() + _, serverEngine := gin.CreateTestContext(serverResp) + + // mocked token validation endpoint used in MustServer + serverEngine.GET("/validate-token", func(c *gin.Context) { + // test that validate-token returning a 401 works as expected + c.Status(http.StatusUnauthorized) + }) + + serverMock := httptest.NewServer(serverEngine) + defer serverMock.Close() + + workerEngine.Use(func(c *gin.Context) { c.Set("server-address", serverMock.URL) }) + + // attach perm middleware that we are testing + workerEngine.Use(MustServer()) + workerEngine.GET("/build/cancel", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + workerMock := httptest.NewServer(workerEngine) + defer workerMock.Close() + + // run test + workerEngine.ServeHTTP(workerCtx.Writer, workerCtx.Request) + + if workerResp.Code != http.StatusUnauthorized { + t.Errorf("MustServer returned %v, want %v", workerResp.Code, http.StatusUnauthorized) + } +} + +func TestPerm_MustServer_ValidateToken404(t *testing.T) { + // setup types + secret := "superSecret" + + // setup context + gin.SetMode(gin.TestMode) + + // setup mock worker router + workerResp := httptest.NewRecorder() + workerCtx, workerEngine := gin.CreateTestContext(workerResp) + + // fake request made to the worker router + workerCtx.Request, _ = http.NewRequest(http.MethodGet, "/build/cancel", nil) + workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) + + // setup mock server router + // the URL of the mock server router is injected into the mock worker router + serverResp := httptest.NewRecorder() + _, serverEngine := gin.CreateTestContext(serverResp) + + // skip mocked token validation endpoint used in MustServer + // test that validate-token returning a 404 works as expected + + serverMock := httptest.NewServer(serverEngine) + defer serverMock.Close() + + workerEngine.Use(func(c *gin.Context) { c.Set("server-address", serverMock.URL) }) + + // attach perm middleware that we are testing + workerEngine.Use(MustServer()) + workerEngine.GET("/build/cancel", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + workerMock := httptest.NewServer(workerEngine) + defer workerMock.Close() + + // run test + workerEngine.ServeHTTP(workerCtx.Writer, workerCtx.Request) + + if workerResp.Code != http.StatusUnauthorized { + t.Errorf("MustServer returned %v, want %v", workerResp.Code, http.StatusUnauthorized) + } +} + +func TestPerm_MustServer_ValidateToken500(t *testing.T) { + // setup types + secret := "superSecret" + + // setup context + gin.SetMode(gin.TestMode) + + // setup mock worker router + workerResp := httptest.NewRecorder() + workerCtx, workerEngine := gin.CreateTestContext(workerResp) + + // fake request made to the worker router + workerCtx.Request, _ = http.NewRequest(http.MethodGet, "/build/cancel", nil) + workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) + + // setup mock server router + // the URL of the mock server router is injected into the mock worker router + serverResp := httptest.NewRecorder() + _, serverEngine := gin.CreateTestContext(serverResp) + + // mocked token validation endpoint used in MustServer + serverEngine.GET("/validate-token", func(c *gin.Context) { + // validate-token returning a server error c.Status(http.StatusInternalServerError) - c.JSON(500, nil) }) - s1 := httptest.NewServer(engine) - defer s1.Close() + + serverMock := httptest.NewServer(serverEngine) + defer serverMock.Close() + + workerEngine.Use(func(c *gin.Context) { c.Set("server-address", serverMock.URL) }) + + // attach perm middleware that we are testing + workerEngine.Use(MustServer()) + workerEngine.GET("/build/cancel", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + workerMock := httptest.NewServer(workerEngine) + defer workerMock.Close() + + // run test + workerEngine.ServeHTTP(workerCtx.Writer, workerCtx.Request) + + if workerResp.Code != http.StatusUnauthorized { + t.Errorf("MustServer returned %v, want %v", workerResp.Code, http.StatusUnauthorized) + } +} + +func TestPerm_MustServer_BadServerAddress(t *testing.T) { + // setup types + secret := "superSecret" + badServerAddress := "test.example.com" + + // setup context + gin.SetMode(gin.TestMode) + + // setup mock worker router + workerResp := httptest.NewRecorder() + workerCtx, workerEngine := gin.CreateTestContext(workerResp) + + // fake request made to the worker router + workerCtx.Request, _ = http.NewRequest(http.MethodGet, "/build/cancel", nil) + workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) + + // setup mock server router + // the URL of the mock server router is injected into the mock worker router + serverResp := httptest.NewRecorder() + _, serverEngine := gin.CreateTestContext(serverResp) + + // skip mocked token validation endpoint used in MustServer + // test that validate-token returning a 404 works as expected + + serverMock := httptest.NewServer(serverEngine) + defer serverMock.Close() + + workerEngine.Use(func(c *gin.Context) { c.Set("server-address", badServerAddress) }) + + // attach perm middleware that we are testing + workerEngine.Use(MustServer()) + workerEngine.GET("/build/cancel", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + workerMock := httptest.NewServer(workerEngine) + defer workerMock.Close() // run test - engine.ServeHTTP(context.Writer, context.Request) + workerEngine.ServeHTTP(workerCtx.Writer, workerCtx.Request) - if resp.Code != http.StatusOK { - t.Errorf("MustServer returned %v, want %v", resp.Code, http.StatusOK) + if workerResp.Code != http.StatusInternalServerError { + t.Errorf("MustServer returned %v, want %v", workerResp.Code, http.StatusInternalServerError) } } -func TestPerm_MustServer_failure(t *testing.T) { +func TestPerm_MustServer_NoToken(t *testing.T) { // setup types - // secret := "foo" - - // u := new(library.User) - // u.SetID(1) - // u.SetName("not-vela-server") - // u.SetToken("bar") - // u.SetHash("baz") - // u.SetAdmin(true) - - // // setup context - // gin.SetMode(gin.TestMode) - - // resp := httptest.NewRecorder() - // context, engine := gin.CreateTestContext(resp) - // context.Request, _ = http.NewRequest(http.MethodGet, "/server/users", nil) - // context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) - - // // setup vela mock server - // engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) - // engine.Use(func(c *gin.Context) { c.Set("user", u) }) - // engine.Use(MustServer()) - // engine.GET("/server/users", func(c *gin.Context) { - // c.Status(http.StatusOK) - // }) - - // s1 := httptest.NewServer(engine) - // defer s1.Close() - - // // run test - // engine.ServeHTTP(context.Writer, context.Request) - - // if resp.Code != http.StatusUnauthorized { - // t.Errorf("MustServer returned %v, want %v", resp.Code, http.StatusUnauthorized) - // } + secret := "" + + // setup context + gin.SetMode(gin.TestMode) + + // setup mock worker router + workerResp := httptest.NewRecorder() + workerCtx, workerEngine := gin.CreateTestContext(workerResp) + + // fake request made to the worker router + workerCtx.Request, _ = http.NewRequest(http.MethodGet, "/build/cancel", nil) + workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) + + // setup mock server router + // the URL of the mock server router is injected into the mock worker router + serverResp := httptest.NewRecorder() + _, serverEngine := gin.CreateTestContext(serverResp) + + // skip mocked token validation endpoint used in MustServer + // test that validate-token returning a 404 works as expected + + serverMock := httptest.NewServer(serverEngine) + defer serverMock.Close() + + workerEngine.Use(func(c *gin.Context) { c.Set("server-address", serverMock.URL) }) + + // attach perm middleware that we are testing + workerEngine.Use(MustServer()) + workerEngine.GET("/build/cancel", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + workerMock := httptest.NewServer(workerEngine) + defer workerMock.Close() + + // run test + workerEngine.ServeHTTP(workerCtx.Writer, workerCtx.Request) + + if workerResp.Code != http.StatusBadRequest { + t.Errorf("MustServer returned %v, want %v", workerResp.Code, http.StatusBadRequest) + } } From 150efa5e2b21fcca171aa62e4ab4f212152961d5 Mon Sep 17 00:00:00 2001 From: davidvader Date: Mon, 27 Mar 2023 15:53:03 -0500 Subject: [PATCH 13/16] chore: tweak comments and return code for invalid parsing --- router/middleware/perm/perm.go | 2 +- router/middleware/perm/perm_test.go | 80 +++++++++++++++++++++++------ 2 files changed, 65 insertions(+), 17 deletions(-) diff --git a/router/middleware/perm/perm.go b/router/middleware/perm/perm.go index f8c51f66..827d6740 100644 --- a/router/middleware/perm/perm.go +++ b/router/middleware/perm/perm.go @@ -30,7 +30,7 @@ func MustServer() gin.HandlerFunc { logrus.Error(err) } - c.AbortWithStatusJSON(http.StatusUnauthorized, err.Error()) + c.AbortWithStatusJSON(http.StatusBadRequest, err.Error()) return } diff --git a/router/middleware/perm/perm_test.go b/router/middleware/perm/perm_test.go index b1d4d6d3..c0e634a0 100644 --- a/router/middleware/perm/perm_test.go +++ b/router/middleware/perm/perm_test.go @@ -15,7 +15,7 @@ import ( func TestPerm_MustServer_ValidateToken200(t *testing.T) { // setup types - secret := "superSecret" + tkn := "superSecret" // setup context gin.SetMode(gin.TestMode) @@ -26,7 +26,7 @@ func TestPerm_MustServer_ValidateToken200(t *testing.T) { // fake request made to the worker router workerCtx.Request, _ = http.NewRequest(http.MethodGet, "/build/cancel", nil) - workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) + workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tkn)) // setup mock server router // the URL of the mock server router is injected into the mock worker router @@ -63,7 +63,7 @@ func TestPerm_MustServer_ValidateToken200(t *testing.T) { func TestPerm_MustServer_ValidateToken401(t *testing.T) { // setup types - secret := "superSecret" + tkn := "superSecret" // setup context gin.SetMode(gin.TestMode) @@ -74,7 +74,7 @@ func TestPerm_MustServer_ValidateToken401(t *testing.T) { // fake request made to the worker router workerCtx.Request, _ = http.NewRequest(http.MethodGet, "/build/cancel", nil) - workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) + workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tkn)) // setup mock server router // the URL of the mock server router is injected into the mock worker router @@ -111,7 +111,7 @@ func TestPerm_MustServer_ValidateToken401(t *testing.T) { func TestPerm_MustServer_ValidateToken404(t *testing.T) { // setup types - secret := "superSecret" + tkn := "superSecret" // setup context gin.SetMode(gin.TestMode) @@ -122,7 +122,7 @@ func TestPerm_MustServer_ValidateToken404(t *testing.T) { // fake request made to the worker router workerCtx.Request, _ = http.NewRequest(http.MethodGet, "/build/cancel", nil) - workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) + workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tkn)) // setup mock server router // the URL of the mock server router is injected into the mock worker router @@ -156,7 +156,7 @@ func TestPerm_MustServer_ValidateToken404(t *testing.T) { func TestPerm_MustServer_ValidateToken500(t *testing.T) { // setup types - secret := "superSecret" + tkn := "superSecret" // setup context gin.SetMode(gin.TestMode) @@ -167,7 +167,7 @@ func TestPerm_MustServer_ValidateToken500(t *testing.T) { // fake request made to the worker router workerCtx.Request, _ = http.NewRequest(http.MethodGet, "/build/cancel", nil) - workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) + workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tkn)) // setup mock server router // the URL of the mock server router is injected into the mock worker router @@ -204,7 +204,7 @@ func TestPerm_MustServer_ValidateToken500(t *testing.T) { func TestPerm_MustServer_BadServerAddress(t *testing.T) { // setup types - secret := "superSecret" + tkn := "superSecret" badServerAddress := "test.example.com" // setup context @@ -216,15 +216,17 @@ func TestPerm_MustServer_BadServerAddress(t *testing.T) { // fake request made to the worker router workerCtx.Request, _ = http.NewRequest(http.MethodGet, "/build/cancel", nil) - workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) + workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tkn)) // setup mock server router // the URL of the mock server router is injected into the mock worker router serverResp := httptest.NewRecorder() _, serverEngine := gin.CreateTestContext(serverResp) - // skip mocked token validation endpoint used in MustServer - // test that validate-token returning a 404 works as expected + // mocked token validation endpoint used in MustServer + serverEngine.GET("/validate-token", func(c *gin.Context) { + c.Status(http.StatusOK) + }) serverMock := httptest.NewServer(serverEngine) defer serverMock.Close() @@ -250,7 +252,7 @@ func TestPerm_MustServer_BadServerAddress(t *testing.T) { func TestPerm_MustServer_NoToken(t *testing.T) { // setup types - secret := "" + tkn := "" // setup context gin.SetMode(gin.TestMode) @@ -261,15 +263,61 @@ func TestPerm_MustServer_NoToken(t *testing.T) { // fake request made to the worker router workerCtx.Request, _ = http.NewRequest(http.MethodGet, "/build/cancel", nil) - workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) + workerCtx.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tkn)) // setup mock server router // the URL of the mock server router is injected into the mock worker router serverResp := httptest.NewRecorder() _, serverEngine := gin.CreateTestContext(serverResp) - // skip mocked token validation endpoint used in MustServer - // test that validate-token returning a 404 works as expected + // mocked token validation endpoint used in MustServer + serverEngine.GET("/validate-token", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + serverMock := httptest.NewServer(serverEngine) + defer serverMock.Close() + + workerEngine.Use(func(c *gin.Context) { c.Set("server-address", serverMock.URL) }) + + // attach perm middleware that we are testing + workerEngine.Use(MustServer()) + workerEngine.GET("/build/cancel", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + workerMock := httptest.NewServer(workerEngine) + defer workerMock.Close() + + // run test + workerEngine.ServeHTTP(workerCtx.Writer, workerCtx.Request) + + if workerResp.Code != http.StatusBadRequest { + t.Errorf("MustServer returned %v, want %v", workerResp.Code, http.StatusBadRequest) + } +} + +func TestPerm_MustServer_NoAuth(t *testing.T) { + // setup context + gin.SetMode(gin.TestMode) + + // setup mock worker router + workerResp := httptest.NewRecorder() + workerCtx, workerEngine := gin.CreateTestContext(workerResp) + + // fake request made to the worker router + workerCtx.Request, _ = http.NewRequest(http.MethodGet, "/build/cancel", nil) + // test that skipping adding an authorization header is handled properly + + // setup mock server router + // the URL of the mock server router is injected into the mock worker router + serverResp := httptest.NewRecorder() + _, serverEngine := gin.CreateTestContext(serverResp) + + // mocked token validation endpoint used in MustServer + serverEngine.GET("/validate-token", func(c *gin.Context) { + c.Status(http.StatusOK) + }) serverMock := httptest.NewServer(serverEngine) defer serverMock.Close() From 6e2e2e57f2ba42a8105b79f4b4a396ebdf996df3 Mon Sep 17 00:00:00 2001 From: davidvader Date: Mon, 27 Mar 2023 16:10:28 -0500 Subject: [PATCH 14/16] chore: remove secret from middleware --- cmd/vela-worker/server.go | 1 - router/middleware/secret.go | 18 ------------- router/middleware/secret_test.go | 46 -------------------------------- 3 files changed, 65 deletions(-) delete mode 100644 router/middleware/secret.go delete mode 100644 router/middleware/secret_test.go diff --git a/cmd/vela-worker/server.go b/cmd/vela-worker/server.go index 38b26447..d9810659 100644 --- a/cmd/vela-worker/server.go +++ b/cmd/vela-worker/server.go @@ -32,7 +32,6 @@ func (w *Worker) server() (http.Handler, *tls.Config) { middleware.RequestVersion, middleware.ServerAddress(w.Config.Server.Address), middleware.Executors(w.Executors), - middleware.Secret(w.Config.Server.Secret), middleware.Logger(logrus.StandardLogger(), time.RFC3339, true), ) diff --git a/router/middleware/secret.go b/router/middleware/secret.go deleted file mode 100644 index c880a425..00000000 --- a/router/middleware/secret.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2022 Target Brands, Inc. All rights reserved. -// -// Use of this source code is governed by the LICENSE file in this repository. - -package middleware - -import ( - "github.com/gin-gonic/gin" -) - -// Secret is a middleware function that attaches the secret used for -// server <-> agent communication to the context of every http.Request. -func Secret(secret string) gin.HandlerFunc { - return func(c *gin.Context) { - c.Set("secret", secret) - c.Next() - } -} diff --git a/router/middleware/secret_test.go b/router/middleware/secret_test.go deleted file mode 100644 index 1f37a084..00000000 --- a/router/middleware/secret_test.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2022 Target Brands, Inc. All rights reserved. -// -// Use of this source code is governed by the LICENSE file in this repository. - -package middleware - -import ( - "net/http" - "net/http/httptest" - "reflect" - "testing" - - "github.com/gin-gonic/gin" -) - -func TestMiddleware_Secret(t *testing.T) { - // setup types - got := "" - want := "foobar" - - // setup context - gin.SetMode(gin.TestMode) - - resp := httptest.NewRecorder() - context, engine := gin.CreateTestContext(resp) - context.Request, _ = http.NewRequest(http.MethodGet, "/health", nil) - - // setup mock server - engine.Use(Secret(want)) - engine.GET("/health", func(c *gin.Context) { - got = c.Value("secret").(string) - - c.Status(http.StatusOK) - }) - - // run test - engine.ServeHTTP(context.Writer, context.Request) - - if resp.Code != http.StatusOK { - t.Errorf("Secret returned %v, want %v", resp.Code, http.StatusOK) - } - - if !reflect.DeepEqual(got, want) { - t.Errorf("Secret is %v, want %v", got, want) - } -} From ee39c05c5aac3fe60a68cc6447adef2e9b58588a Mon Sep 17 00:00:00 2001 From: davidvader Date: Tue, 28 Mar 2023 09:47:31 -0500 Subject: [PATCH 15/16] fix: remove c.Error --- router/middleware/perm/perm.go | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/router/middleware/perm/perm.go b/router/middleware/perm/perm.go index 827d6740..68f62792 100644 --- a/router/middleware/perm/perm.go +++ b/router/middleware/perm/perm.go @@ -23,14 +23,11 @@ func MustServer() gin.HandlerFunc { // retrieve the callers token from the request headers tkn, err := token.Retrieve(c.Request) if err != nil { - msg := fmt.Sprintf("error parsing token: %s", err) + msg := fmt.Sprintf("error parsing token: %v", err) - err := c.Error(fmt.Errorf(msg)) - if err != nil { - logrus.Error(err) - } + logrus.Error(msg) - c.AbortWithStatusJSON(http.StatusBadRequest, err.Error()) + c.AbortWithStatusJSON(http.StatusBadRequest, types.Error{Message: &msg}) return } @@ -40,10 +37,7 @@ func MustServer() gin.HandlerFunc { if !ok { msg := "error retrieving server address" - err := c.Error(fmt.Errorf(msg)) - if err != nil { - logrus.Error(err) - } + logrus.Error(msg) c.AbortWithStatusJSON(http.StatusInternalServerError, types.Error{Message: &msg}) @@ -55,10 +49,7 @@ func MustServer() gin.HandlerFunc { if err != nil { msg := fmt.Sprintf("error creating vela client: %s", err) - err := c.Error(fmt.Errorf(msg)) - if err != nil { - logrus.Error(err) - } + logrus.Error(msg) c.AbortWithStatusJSON(http.StatusInternalServerError, types.Error{Message: &msg}) @@ -69,10 +60,7 @@ func MustServer() gin.HandlerFunc { if strings.EqualFold(tkn, "") { msg := "missing token" - err := c.Error(fmt.Errorf(msg)) - if err != nil { - logrus.Error(err) - } + logrus.Error(msg) c.AbortWithStatusJSON(http.StatusBadRequest, types.Error{Message: &msg}) @@ -87,10 +75,7 @@ func MustServer() gin.HandlerFunc { if err != nil { msg := fmt.Sprintf("error validating token: %s", err) - err := c.Error(fmt.Errorf(msg)) - if err != nil { - logrus.Error(err) - } + logrus.Error(msg) c.AbortWithStatusJSON(http.StatusInternalServerError, types.Error{Message: &msg}) @@ -101,10 +86,7 @@ func MustServer() gin.HandlerFunc { if resp.StatusCode != http.StatusOK { msg := "unable to validate token" - err := c.Error(fmt.Errorf(msg)) - if err != nil { - logrus.Error(err) - } + logrus.Error(msg) c.AbortWithStatusJSON(http.StatusUnauthorized, types.Error{Message: &msg}) From 2cb0af650d8240af4ef3806f95cce4bf54bae3e9 Mon Sep 17 00:00:00 2001 From: davidvader Date: Tue, 28 Mar 2023 10:04:10 -0500 Subject: [PATCH 16/16] fix: remove exist check from MustGet --- router/middleware/perm/perm.go | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/router/middleware/perm/perm.go b/router/middleware/perm/perm.go index 68f62792..85dd60d8 100644 --- a/router/middleware/perm/perm.go +++ b/router/middleware/perm/perm.go @@ -33,16 +33,7 @@ func MustServer() gin.HandlerFunc { } // retrieve the configured server address from the context - addr, ok := c.MustGet("server-address").(string) - if !ok { - msg := "error retrieving server address" - - logrus.Error(msg) - - c.AbortWithStatusJSON(http.StatusInternalServerError, types.Error{Message: &msg}) - - return - } + addr := c.MustGet("server-address").(string) // create a temporary client to validate the incoming request vela, err := vela.NewClient(addr, "vela-worker", nil)