mirror of
https://github.com/gomods/athens
synced 2026-02-03 13:20:30 +00:00
* The proxy middleware calls an hook if set to check if the module needs to be filtered * Fixed error handling * Added a middleware func that passes the log entry down to other middlewares * Split the filter middleware in two * Moved validation middleware in its own file * Renamed filter to middleware, all the middleware stuff in a single file * Moved default hook to empty string * Split tests of filter middleware from validation middleware * Installed the validation middleware only if the hook is set * Moved filter test to middleware test * Fixed gofmt issue caused by manual merge * Fixed wrong logrus import * Removed logger from filter middleware * Moved middleware functions to own package * Removed unused argument, fixed errors * Fixed gofmt errors * Made middleware func private * Changed debuglevel from string to enum * Added comments to now public functions * Changed module alias to a shorter one * Removed white space * Split middleware in separate files, injected the hook as param * Removed commented code
80 lines
2.0 KiB
Go
80 lines
2.0 KiB
Go
package middleware
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
"github.com/bketelsen/buffet"
|
|
"github.com/gobuffalo/buffalo"
|
|
"github.com/gomods/athens/pkg/errors"
|
|
"github.com/gomods/athens/pkg/log"
|
|
"github.com/gomods/athens/pkg/paths"
|
|
)
|
|
|
|
// NewValidationMiddleware builds a middleware function that performs validation checks by calling
|
|
// an external webhook
|
|
func NewValidationMiddleware(entry log.Entry, validatorHook string) buffalo.MiddlewareFunc {
|
|
const op errors.Op = "actions.ValidationMiddleware"
|
|
|
|
return func(next buffalo.Handler) buffalo.Handler {
|
|
return func(c buffalo.Context) error {
|
|
sp := buffet.SpanFromContext(c).SetOperationName("validationMiddleware")
|
|
defer sp.Finish()
|
|
|
|
mod, err := paths.GetModule(c)
|
|
|
|
if err != nil {
|
|
// if there is no module the path we are hitting is not one related to modules, like /
|
|
return next(c)
|
|
}
|
|
|
|
// not checking the error. Not all requests include a version
|
|
// i.e. list requests path is like /{module:.+}/@v/list with no version parameter
|
|
version, _ := paths.GetVersion(c)
|
|
|
|
if version != "" {
|
|
valid, err := validate(validatorHook, mod, version)
|
|
if err != nil {
|
|
entry.SystemErr(err)
|
|
return c.Render(http.StatusInternalServerError, nil)
|
|
}
|
|
|
|
if !valid {
|
|
return c.Render(http.StatusForbidden, nil)
|
|
}
|
|
}
|
|
return next(c)
|
|
}
|
|
}
|
|
}
|
|
|
|
type validationParams struct {
|
|
Module string
|
|
Version string
|
|
}
|
|
|
|
func validate(hook, mod, ver string) (bool, error) {
|
|
const op errors.Op = "actions.validate"
|
|
|
|
toVal := &validationParams{mod, ver}
|
|
jsonVal, err := json.Marshal(toVal)
|
|
if err != nil {
|
|
return false, errors.E(op, err)
|
|
}
|
|
|
|
resp, err := http.Post(hook, "application/json", bytes.NewBuffer(jsonVal))
|
|
if err != nil {
|
|
return false, errors.E(op, err)
|
|
}
|
|
|
|
switch {
|
|
case resp.StatusCode == http.StatusOK:
|
|
return true, nil
|
|
case resp.StatusCode == http.StatusForbidden:
|
|
return false, nil
|
|
default:
|
|
return false, errors.E(op, "Unexpected status code ", resp.StatusCode)
|
|
}
|
|
}
|