Skip to content

Commit

Permalink
- Added support for basic auth (CENTRY_SERVE_USERNAME and CENTRY_SERV…
Browse files Browse the repository at this point in the history
…E_PASSWORD).
  • Loading branch information
Kristoffer Ahl committed Jun 1, 2019
1 parent 9c15ada commit a516741
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 11 deletions.
19 changes: 18 additions & 1 deletion cmd/centry/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"os"
"strings"

api "github.com/kristofferahl/go-centry/internal/pkg/api"
Expand All @@ -23,7 +24,8 @@ func (sc *ServeCommand) Run(args []string) int {
sc.Log.Debugf("Serving HTTP api")

s := api.NewServer(api.Config{
Log: sc.Log,
Log: sc.Log,
BasicAuth: configureBasicAuth(),
})

s.Router.HandleFunc("/", sc.indexHandler()).Methods("GET")
Expand All @@ -47,6 +49,21 @@ func (sc *ServeCommand) Synopsis() string {
return "Exposes commands over HTTP"
}

func configureBasicAuth() *api.BasicAuth {
var auth *api.BasicAuth
baUsername := os.Getenv("CENTRY_SERVE_USERNAME")
baPassword := os.Getenv("CENTRY_SERVE_PASSWORD")

if baUsername != "" && baPassword != "" {
auth = &api.BasicAuth{
Username: baUsername,
Password: baPassword,
}
}

return auth
}

func (sc *ServeCommand) indexHandler() func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
statusCode := http.StatusOK
Expand Down
73 changes: 63 additions & 10 deletions internal/pkg/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ import (

// Config defines server configuration
type Config struct {
Log *logrus.Entry
Log *logrus.Entry
BasicAuth *BasicAuth
}

// BasicAuth defines basic auth configuration
type BasicAuth struct {
Username string
Password string
}

// Server holds the configuration, router and http server
Expand All @@ -29,6 +36,7 @@ func NewServer(config Config) Server {
}

s.Router.Use(loggingMiddleware(config))
s.Router.Use(basicAuthMiddleware(config))

s.Server = &http.Server{
Handler: s.Router,
Expand All @@ -37,10 +45,22 @@ func NewServer(config Config) Server {
WriteTimeout: 30 * time.Second,
}

config.Log.WithFields(logrus.Fields{
auth := "none"
if config.BasicAuth != nil {
auth = "basic"
}

l := config.Log.WithFields(logrus.Fields{
"service": "HTTP-Server",
"address": s.Server.Addr,
}).Infof("listening on %s", s.Server.Addr)
"auth": auth,
})

if auth != "basic" {
l.Warnf("listening on %s", s.Server.Addr)
} else {
l.Infof("listening on %s", s.Server.Addr)
}

return s
}
Expand All @@ -50,23 +70,56 @@ func (s Server) RunAndBlock() error {
return s.Server.ListenAndServe()
}

func basicAuthMiddleware(config Config) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ba := config.BasicAuth
if ba == nil {
next.ServeHTTP(w, r)
return
}

user, pass, _ := r.BasicAuth()

if (*ba).Username != user || (*ba).Password != pass {
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
http.Error(w, "Unauthorized.", http.StatusUnauthorized)
config.Log.WithFields(logrus.Fields{
"service": "HTTP-Server",
"middleware": "basic-auth",
}).Debugf("Authentication failed")
return
}

config.Log.WithFields(logrus.Fields{
"service": "HTTP-Server",
"middleware": "basic-auth",
}).Debugf("Successfully authenticated")

next.ServeHTTP(w, r)
})
}
}

func loggingMiddleware(config Config) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
config.Log.WithFields(logrus.Fields{
"service": "HTTP-Server",
"method": r.Method,
"path": r.RequestURI,
"direction": "incoming",
"service": "HTTP-Server",
"middleware": "logging",
"method": r.Method,
"path": r.RequestURI,
"direction": "incoming",
}).Debugf("HTTP %s %s", r.Method, r.RequestURI)

scrw := &statusCodeResponseWriter{w, http.StatusOK}
next.ServeHTTP(scrw, r)

config.Log.WithFields(logrus.Fields{
"service": "HTTP-Server",
"status": scrw.statusCode,
"direction": "outgoing",
"service": "HTTP-Server",
"middleware": "logging",
"status": scrw.statusCode,
"direction": "outgoing",
}).Debugf("HTTP %s %s - %d %s", r.Method, r.RequestURI, scrw.statusCode, http.StatusText(scrw.statusCode))
})
}
Expand Down

0 comments on commit a516741

Please sign in to comment.