From 12b58d5e542fe8af5b97e1017526e5460ee9a151 Mon Sep 17 00:00:00 2001 From: Mathis Joffre Date: Thu, 25 Aug 2022 14:48:02 +0200 Subject: [PATCH] Issues fix Signed-off-by: Mathis Joffre --- README.md | 120 +++++++++++++++++-------------------- config/base_config.go | 3 +- config/base_config_test.go | 18 +++--- fiber_middleware.go | 12 ++-- gin_middleware.go | 6 +- internal/utils.go | 6 +- 6 files changed, 82 insertions(+), 83 deletions(-) diff --git a/README.md b/README.md index 6c51401..e0b3ca7 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ go get github.com/Joffref/opa-middleware package main import ( + "github.com/Joffref/opa-middleware" "github.com/Joffref/opa-middleware/config" - "github.com/Joffref/opa-middleware/middleware/http" "net/http" ) @@ -42,7 +42,7 @@ func (h *H) ServeHTTP(w http.ResponseWriter, r *http.Request) { } func main() { - handler, err := httpmiddleware.NewHTTPMiddleware( + handler, err := opamiddleware.NewHTTPMiddleware( &config.Config{ Policy: Policy, Query: "data.policy.allow", @@ -63,7 +63,8 @@ func main() { if err != nil { panic(err) } - err = http.ListenAndServe(":8080", handler) + http.HandleFunc("/", handler.ServeHTTP) + err = http.ListenAndServe(":8080", nil) if err != nil { return } @@ -71,13 +72,13 @@ func main() { ``` ### Remote based policy engine - +The policy is the same as above, but the policy is stored in a remote server. ```go package main import ( + "github.com/Joffref/opa-middleware" "github.com/Joffref/opa-middleware/config" - "github.com/Joffref/opa-middleware/middleware/http" "net/http" ) @@ -90,10 +91,10 @@ func (h *H) ServeHTTP(w http.ResponseWriter, r *http.Request) { } func main() { - handler, err := httpmiddleware.NewHTTPMiddleware( + handler, err := opamiddleware.NewHTTPMiddleware( &config.Config{ - URL: "http://localhost:8181", - Query: "data.policy.allow", + URL: "http://localhost:8181/", + Query: "data.policy.allow", InputCreationMethod: func(r *http.Request) (map[string]interface{}, error) { return map[string]interface{}{ "path": r.URL.Path, @@ -111,7 +112,8 @@ func main() { if err != nil { panic(err) } - err = http.ListenAndServe(":8080", handler) + http.HandleFunc("/", handler.ServeHTTP) + err = http.ListenAndServe(":8080", nil) if err != nil { return } @@ -123,38 +125,38 @@ func main() { package main import ( - "github.com/Joffref/opa-middleware/config" - ginmiddleware "github.com/Joffref/opa-middleware/middleware/gin" - "github.com/gin-gonic/gin" + "github.com/Joffref/opa-middleware" + "github.com/Joffref/opa-middleware/config" + "github.com/gin-gonic/gin" ) func main() { - r := gin.Default() - r.GET("/ping", func(c *gin.Context) { - c.JSON(200, gin.H{ - "message": "pong", - }) - }) - middleware, err := ginmiddleware.NewGinMiddleware( - &config.Config{ - URL: "https://opa.example.com/", - Query: "data.policy.allow", - }, - func(c *gin.Context) (map[string]interface{}, error) { - return map[string]interface{}{ - "path": c.Request.URL.Path, - "method": c.Request.Method, - }, nil - }, - ) - if err != nil { - return - } - r.Use(middleware.Use()) - err = r.Run(":8080") - if err != nil { - return - } + r := gin.Default() + middleware, err := opamiddleware.NewGinMiddleware( + &config.Config{ + URL: "http://localhost:8181/", + Query: "data.policy.allow", + ExceptedResult: true, + DeniedStatusCode: 403, + DeniedMessage: "Forbidden", + }, + func(c *gin.Context) (map[string]interface{}, error) { + return map[string]interface{}{ + "path": c.Request.URL.Path, + "method": c.Request.Method, + }, nil + }, + ) + if err != nil { + return + } + r.Use(middleware.Use()) + r.GET("/ping", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "pong", + }) + }) + r.Run(":8080") } ``` @@ -163,35 +165,21 @@ func main() { package main import ( + "github.com/Joffref/opa-middleware" "github.com/Joffref/opa-middleware/config" - fibermiddleware "github.com/Joffref/opa-middleware/middleware/fiber" "github.com/gofiber/fiber/v2" - "log" - "time" ) func main() { app := fiber.New() - app.Get("/", func(c *fiber.Ctx) error { - return c.SendString("Hello World!") - }) - - middleware, err := fibermiddleware.NewFiberMiddleware(&config.Config{ - URL: "http://localhost:8080/", - Query: "data.policy.allow", - DeniedStatusCode: 403, - DeniedMessage: "Forbidden", - Headers: map[string]string{ - "Content-Type": "application/json", - }, - IgnoredHeaders: []string{ - "X-Request-Id", + middleware, err := opamiddleware.NewFiberMiddleware( + &config.Config{ + URL: "http://localhost:8181/", + Query: "data.policy.allow", + ExceptedResult: true, + DeniedStatusCode: 403, + DeniedMessage: "Forbidden", }, - Debug: true, - Logger: log.New(log.Writer(), "", log.LstdFlags), - ExceptedResult: true, - Timeout: 5 * time.Second, - }, func(c *fiber.Ctx) (map[string]interface{}, error) { return map[string]interface{}{ "path": c.Path(), @@ -203,9 +191,13 @@ func main() { return } app.Use(middleware.Use()) - err = app.Listen(":3000") - if err != nil { - return - } + app.Get("/ping", func(c *fiber.Ctx) error { + err := c.JSON("pong") + if err != nil { + return err + } + return nil + }) + app.Listen(":8080") } ``` \ No newline at end of file diff --git a/config/base_config.go b/config/base_config.go index a466ec5..63bdc9f 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -38,7 +38,7 @@ type Config struct { // Headers is a list of headers to send to the OPA server. // All headers are sent to the OPA server except those in the IgnoredHeaders list. - Headers map[string]string `json:"headers,omitempty"` + Headers map[string][]string `json:"headers,omitempty"` // IgnoredHeaders is a list of headers to ignore when sending to the OPA server. IgnoredHeaders []string `json:"excepted_headers,omitempty"` @@ -61,7 +61,6 @@ func (c *Config) Validate() error { c.Logger = log.Default() } } - c.ExceptedResult = true if c.Timeout == 0 { c.Timeout = 10 * time.Second } diff --git a/config/base_config_test.go b/config/base_config_test.go index f7a3d28..d4c2025 100644 --- a/config/base_config_test.go +++ b/config/base_config_test.go @@ -18,7 +18,7 @@ func TestConfig_Validate(t *testing.T) { ExceptedResult bool DeniedStatusCode int DeniedMessage string - Headers map[string]string + Headers map[string][]string IgnoredHeaders []string Debug bool Logger *log.Logger @@ -40,8 +40,8 @@ func TestConfig_Validate(t *testing.T) { ExceptedResult: true, DeniedStatusCode: http.StatusForbidden, DeniedMessage: "Forbidden", - Headers: map[string]string{ - "Content-Type": "application/json", + Headers: map[string][]string{ + "Content-Type": {"application/json"}, }, IgnoredHeaders: []string{ "Content-Type", @@ -62,8 +62,8 @@ func TestConfig_Validate(t *testing.T) { ExceptedResult: true, DeniedStatusCode: http.StatusForbidden, DeniedMessage: "Forbidden", - Headers: map[string]string{ - "Content-Type": "application/json", + Headers: map[string][]string{ + "Content-Type": {"application/json"}, }, }, wantErr: true, @@ -78,8 +78,8 @@ func TestConfig_Validate(t *testing.T) { ExceptedResult: true, DeniedStatusCode: http.StatusForbidden, DeniedMessage: "Forbidden", - Headers: map[string]string{ - "Content-Type": "application/json", + Headers: map[string][]string{ + "Content-Type": {"application/json"}, }, }, wantErr: true, @@ -94,8 +94,8 @@ func TestConfig_Validate(t *testing.T) { ExceptedResult: true, DeniedStatusCode: http.StatusForbidden, DeniedMessage: "Forbidden", - Headers: map[string]string{ - "Content-Type": "application/json", + Headers: map[string][]string{ + "Content-Type": {"application/json"}, }, IgnoredHeaders: []string{ "Content-Type", diff --git a/fiber_middleware.go b/fiber_middleware.go index a97d490..852c591 100644 --- a/fiber_middleware.go +++ b/fiber_middleware.go @@ -79,13 +79,17 @@ func (g *FiberMiddleware) query(c *fiber.Ctx) (bool, error) { } func transformFastHTTP(ctx *fasthttp.RequestCtx) *http.Request { - req := &http.Request{} - headers := make(map[string]string) + req := &http.Request{ + Header: make(http.Header), + } + headers := make(map[string][]string) ctx.Request.Header.VisitAll(func(key, value []byte) { - headers[string(key)] = string(value) + headers[string(key)] = append(headers[string(key)], string(value)) }) for k, v := range headers { - req.Header.Set(k, v) + for _, vv := range v { + req.Header.Add(k, vv) + } } req = req.WithContext(ctx) return req diff --git a/gin_middleware.go b/gin_middleware.go index a727fb3..fa66de7 100644 --- a/gin_middleware.go +++ b/gin_middleware.go @@ -51,14 +51,16 @@ func (g *GinMiddleware) Use() func(c *gin.Context) { if g.Config.Debug { g.Config.Logger.Printf("[opa-middleware-gin] Error: %s", err.Error()) } - c.AbortWithError(http.StatusInternalServerError, err) + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + c.AbortWithStatus(http.StatusInternalServerError) return } if g.Config.Debug { g.Config.Logger.Printf("[opa-middleware-gin] Result: %t", result) } if result != g.Config.ExceptedResult { - c.AbortWithError(g.Config.DeniedStatusCode, errors.New(g.Config.DeniedMessage)) + c.JSON(g.Config.DeniedStatusCode, gin.H{"error": g.Config.DeniedMessage}) + c.AbortWithStatus(g.Config.DeniedStatusCode) return } c.Next() diff --git a/internal/utils.go b/internal/utils.go index 47c7dc9..c46cdd0 100644 --- a/internal/utils.go +++ b/internal/utils.go @@ -12,8 +12,10 @@ func buildHeaders(r *http.Request, cfg *config.Config) (http.Header, error) { for _, header := range cfg.IgnoredHeaders { headers.Del(header) } - for header, value := range cfg.Headers { - headers.Set(header, value) + for header, values := range cfg.Headers { + for _, value := range values { + headers.Set(header, value) + } } return headers, nil }