github.com/gocaveman/caveman@v0.0.0-20191211162744-0ddf99dbdf6e/webutil/http-basic-auth-handler.go (about)

     1  package webutil
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  )
     7  
     8  // NewBasicAuthOneHandler creates a new BasicAuthHandler using the defaults.
     9  func NewBasicAuthOneHandler(username, password string) *BasicAuthHandler {
    10  	return &BasicAuthHandler{
    11  		IncludePathPrefixes: []string{"/"},
    12  		ExcludePathPrefixes: []string{"/.well-known"},
    13  		CheckLogin:          NewCheckLoginOneFunc(username, password),
    14  		Realm:               "restricted access",
    15  	}
    16  }
    17  
    18  // BasicAuthHandler will redirect all requests which do not have r.URL.Scheme=="https".
    19  type BasicAuthHandler struct {
    20  	IncludePathPrefixes []string                             // include these path prefixes
    21  	ExcludePathPrefixes []string                             // exclude these path prefixes
    22  	CheckLogin          func(username, password string) bool // check usernamd and password for validity
    23  	Realm               string
    24  }
    25  
    26  // NewCheckLoginOneFunc returns a function that checks for the validity of a username and password.
    27  func NewCheckLoginOneFunc(username, password string) func(username, password string) bool {
    28  	return func(checkUsername, checkPassword string) bool {
    29  		return username == checkUsername && password == checkPassword
    30  	}
    31  }
    32  
    33  func (h *BasicAuthHandler) ServeHTTPChain(w http.ResponseWriter, r *http.Request) (http.ResponseWriter, *http.Request) {
    34  
    35  	check := false
    36  
    37  	for _, k := range h.IncludePathPrefixes {
    38  		if HasPathPrefix(r.URL.Path, k) {
    39  			check = true
    40  			break
    41  		}
    42  	}
    43  
    44  	for _, k := range h.ExcludePathPrefixes {
    45  		if HasPathPrefix(r.URL.Path, k) {
    46  			check = false
    47  			break
    48  		}
    49  	}
    50  
    51  	if check {
    52  		u, p, ok := r.BasicAuth()
    53  		if ok {
    54  			if h.CheckLogin(u, p) {
    55  				return w, r // login matches, pass through
    56  			}
    57  		}
    58  
    59  		// check required but logic failed, send back 401
    60  		w.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic realm=%q", h.Realm))
    61  		http.Error(w, "Unauthorized", 401)
    62  	}
    63  
    64  	return w, r
    65  }