| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 | package middlewareimport (	"encoding/base64"	"strconv"	"strings"	"github.com/labstack/echo")type (	// BasicAuthConfig defines the config for BasicAuth middleware.	BasicAuthConfig struct {		// Skipper defines a function to skip middleware.		Skipper Skipper		// Validator is a function to validate BasicAuth credentials.		// Required.		Validator BasicAuthValidator		// Realm is a string to define realm attribute of BasicAuth.		// Default value "Restricted".		Realm string	}	// BasicAuthValidator defines a function to validate BasicAuth credentials.	BasicAuthValidator func(string, string, echo.Context) (bool, error))const (	basic        = "basic"	defaultRealm = "Restricted")var (	// DefaultBasicAuthConfig is the default BasicAuth middleware config.	DefaultBasicAuthConfig = BasicAuthConfig{		Skipper: DefaultSkipper,		Realm:   defaultRealm,	})// BasicAuth returns an BasicAuth middleware.//// For valid credentials it calls the next handler.// For missing or invalid credentials, it sends "401 - Unauthorized" response.func BasicAuth(fn BasicAuthValidator) echo.MiddlewareFunc {	c := DefaultBasicAuthConfig	c.Validator = fn	return BasicAuthWithConfig(c)}// BasicAuthWithConfig returns an BasicAuth middleware with config.// See `BasicAuth()`.func BasicAuthWithConfig(config BasicAuthConfig) echo.MiddlewareFunc {	// Defaults	if config.Validator == nil {		panic("echo: basic-auth middleware requires a validator function")	}	if config.Skipper == nil {		config.Skipper = DefaultBasicAuthConfig.Skipper	}	if config.Realm == "" {		config.Realm = defaultRealm	}	return func(next echo.HandlerFunc) echo.HandlerFunc {		return func(c echo.Context) error {			if config.Skipper(c) {				return next(c)			}			auth := c.Request().Header.Get(echo.HeaderAuthorization)			l := len(basic)			if len(auth) > l+1 && strings.ToLower(auth[:l]) == basic {				b, err := base64.StdEncoding.DecodeString(auth[l+1:])				if err != nil {					return err				}				cred := string(b)				for i := 0; i < len(cred); i++ {					if cred[i] == ':' {						// Verify credentials						valid, err := config.Validator(cred[:i], cred[i+1:], c)						if err != nil {							return err						} else if valid {							return next(c)						}						break					}				}			}			realm := defaultRealm			if config.Realm != defaultRealm {				realm = strconv.Quote(config.Realm)			}			// Need to return `401` for browsers to pop-up login box.			c.Response().Header().Set(echo.HeaderWWWAuthenticate, basic+" realm="+realm)			return echo.ErrUnauthorized		}	}}
 |