From 658bf80d54daa890f3f4baa75e9840aa0f0c3c9f Mon Sep 17 00:00:00 2001 From: Thomas von Rosenberg Date: Fri, 17 Jun 2022 10:07:55 +0200 Subject: [PATCH] Secure POST /report via basic auth --- api/api.go | 36 ++++++++++++++++++++++++++++++++---- main.go | 9 ++++++++- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/api/api.go b/api/api.go index 97a0825..df8c6b6 100644 --- a/api/api.go +++ b/api/api.go @@ -10,7 +10,7 @@ import ( "github.com/labstack/echo/v4/middleware" ) -func New(db *sqlx.DB) *echo.Echo { +func New(db *sqlx.DB, token string) *echo.Echo { app := echo.New() app.Use(middleware.Recover()) app.HTTPErrorHandler = func(err error, c echo.Context) { @@ -28,9 +28,14 @@ func New(db *sqlx.DB) *echo.Echo { }) } - wrapper := ServerInterfaceWrapper{Handler: &api{db: db}} + wrapper := ServerInterfaceWrapper{ + Handler: &api{ + db: db, + token: token, + }, + } - app.POST("/report/:commit", wrapper.AddReport) + app.POST("/report/:commit", secure(token, wrapper.AddReport)) app.GET("/flakes", wrapper.GetFlakyTests) spec, err := GetSwagger() @@ -42,6 +47,29 @@ func New(db *sqlx.DB) *echo.Echo { return app } + +func secure(token string, handler echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + user, pass, ok := c.Request().BasicAuth() + + if !ok { + return unauthorized(c, "noflake", "no credentials provided") + } + + if user != "token" || pass != token{ + return unauthorized(c, "noflake", "wrong credentials") + } + + return handler(c) + } +} + +func unauthorized(c echo.Context, realm, reason string) error { + c.Response().Header().Set("WWW-Authenticate", `Basic realm="`+realm+`"`) + return echo.NewHTTPError(http.StatusUnauthorized, reason) +} + type api struct { - db *sqlx.DB + db *sqlx.DB + token string } diff --git a/main.go b/main.go index dc742cc..42f6d48 100644 --- a/main.go +++ b/main.go @@ -31,10 +31,17 @@ func main() { EnvVars: []string{"NOFLAKE_DB"}, Value: "noflake.sqlite3", }, + &cli.StringFlag{ + Name: "token", + Usage: "token to secure the POST endpoints", + EnvVars: []string{"NOFLAKE_TOKEN"}, + Required: true, + }, }, Action: func(c *cli.Context) error { db := database.New(c.String("db")) - webapi := api.New(db) + token := c.String("token") + webapi := api.New(db, token) listenAddr := c.String("address") log.Info().Str("address", listenAddr).Msg("HTTP")