MailHog/vendor/github.com/mailhog/http/server.go

113 lines
2.3 KiB
Go
Raw Permalink Normal View History

2017-04-16 23:42:21 +00:00
package http
import (
"bytes"
"io"
"io/ioutil"
"net/http"
"os"
"strings"
"github.com/gorilla/pat"
"github.com/ian-kent/go-log/log"
"golang.org/x/crypto/bcrypt"
)
// Authorised should be given a function to enable HTTP Basic Authentication
var Authorised func(string, string) bool
var users map[string]string
// AuthFile sets Authorised to a function which validates against file
func AuthFile(file string) {
users = make(map[string]string)
b, err := ioutil.ReadFile(file)
if err != nil {
log.Fatalf("[HTTP] Error reading auth-file: %s", err)
// FIXME - go-log
os.Exit(1)
}
buf := bytes.NewBuffer(b)
for {
l, err := buf.ReadString('\n')
l = strings.TrimSpace(l)
if len(l) > 0 {
p := strings.SplitN(l, ":", 2)
if len(p) < 2 {
log.Fatalf("[HTTP] Error reading auth-file, invalid line: %s", l)
// FIXME - go-log
os.Exit(1)
}
users[p[0]] = p[1]
}
switch {
case err == io.EOF:
break
case err != nil:
log.Fatalf("[HTTP] Error reading auth-file: %s", err)
// FIXME - go-log
os.Exit(1)
break
}
if err == io.EOF {
break
} else if err != nil {
}
}
log.Printf("[HTTP] Loaded %d users from %s", len(users), file)
Authorised = func(u, pw string) bool {
hpw, ok := users[u]
if !ok {
return false
}
err := bcrypt.CompareHashAndPassword([]byte(hpw), []byte(pw))
if err != nil {
return false
}
return true
}
}
// BasicAuthHandler is middleware to check HTTP Basic Authentication
// if an authorisation function is defined.
func BasicAuthHandler(h http.Handler) http.Handler {
f := func(w http.ResponseWriter, req *http.Request) {
if Authorised == nil {
h.ServeHTTP(w, req)
return
}
u, pw, ok := req.BasicAuth()
if !ok || !Authorised(u, pw) {
w.Header().Set("WWW-Authenticate", "Basic")
w.WriteHeader(401)
return
}
h.ServeHTTP(w, req)
}
return http.HandlerFunc(f)
}
// Listen binds to httpBindAddr
func Listen(httpBindAddr string, Asset func(string) ([]byte, error), exitCh chan int, registerCallback func(http.Handler)) {
log.Info("[HTTP] Binding to address: %s", httpBindAddr)
pat := pat.New()
registerCallback(pat)
//compress := handlers.CompressHandler(pat)
auth := BasicAuthHandler(pat) //compress)
err := http.ListenAndServe(httpBindAddr, auth)
if err != nil {
log.Fatalf("[HTTP] Error binding to address %s: %s", httpBindAddr, err)
}
}