Skip to content

Commit

Permalink
Add HTTP authentication for mailhog/MailHog#40
Browse files Browse the repository at this point in the history
  • Loading branch information
ian-kent committed May 27, 2015
1 parent f0ff7c5 commit 2b70b1a
Showing 1 changed file with 83 additions and 1 deletion.
84 changes: 83 additions & 1 deletion server.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,102 @@
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
}
}

// 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)

err := http.ListenAndServe(httpBindAddr, pat)
f := func(w http.ResponseWriter, req *http.Request) {
if Authorised == nil {
pat.ServeHTTP(w, req)
return
}

u, pw, ok := req.BasicAuth()
if !ok || !Authorised(u, pw) {
w.Header().Set("WWW-Authenticate", "Basic")
w.WriteHeader(401)
return
}
pat.ServeHTTP(w, req)
}

err := http.ListenAndServe(httpBindAddr, http.HandlerFunc(f))
if err != nil {
log.Fatalf("[HTTP] Error binding to address %s: %s", httpBindAddr, err)
}
Expand Down

0 comments on commit 2b70b1a

Please sign in to comment.