Skip to content

Commit

Permalink
whauth.RequireBasicAuth and some mux improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
jtolio committed Jan 25, 2017
1 parent 8cfe5ff commit cd8c17f
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 19 deletions.
35 changes: 35 additions & 0 deletions whauth/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (C) 2016 JT Olds
// See LICENSE for copying information

// Package whauth provides some helper methods and handlers for dealing with
// HTTP basic auth
package whauth // import "gopkg.in/webhelp.v1/whauth"

import (
"net/http"

"gopkg.in/webhelp.v1/wherr"
"gopkg.in/webhelp.v1/whroute"
)

// RequireBasicAuth ensures that a valid user is provided, calling
// wherr.Handle with wherr.Unauthorized if not.
func RequireBasicAuth(h http.Handler, realm string,
valid func(user, pass string) bool) http.Handler {
return whroute.HandlerFunc(h,
func(w http.ResponseWriter, r *http.Request) {
user, pass, ok := r.BasicAuth()
if !ok {
w.Header().Set("WWW-Authenticate", `Basic realm="`+realm+`"`)
wherr.Handle(w, r, wherr.Unauthorized.New("basic auth required"))
return
}
if !valid(user, pass) {
w.Header().Set("WWW-Authenticate", `Basic realm="`+realm+`"`)
wherr.Handle(w, r,
wherr.Unauthorized.New("invalid username or password"))
return
}
h.ServeHTTP(w, r)
})
}
3 changes: 3 additions & 0 deletions whmux/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ func (d Dir) ServeHTTP(w http.ResponseWriter, r *http.Request) {
wherr.Handle(w, r, wherr.NotFound.New("resource: %#v", dir))
return
}
if left == "" {
left = "/"
}
r.URL.Path = left
handler.ServeHTTP(w, r)
}
Expand Down
62 changes: 43 additions & 19 deletions whredir/redirect.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,19 @@ func (f RedirectHandlerFunc) Routes(
var _ http.Handler = RedirectHandlerFunc(nil)
var _ whroute.Lister = RedirectHandlerFunc(nil)

// FullURL returns the full url from the incoming request, regardless of
// what current whmux.Dir is involved or how req.URL.Path has been edited.
func FullURL(r *http.Request) (*url.URL, error) {
u, err := url.ParseRequestURI(r.RequestURI)
if err != nil {
return nil, err
}
u.Scheme = r.URL.Scheme
u.Host = r.URL.Host
u.User = r.URL.User
return u, nil
}

// RequireHTTPS returns a handler that will redirect to the same path but using
// https if https was not already used.
func RequireHTTPS(handler http.Handler) http.Handler {
Expand All @@ -71,14 +84,12 @@ func RequireHTTPS(handler http.Handler) http.Handler {
handler.ServeHTTP(w, r)
return
}
u, err := url.ParseRequestURI(r.RequestURI)
u, err := FullURL(r)
if err != nil {
wherr.Handle(w, r, err)
return
}
u.Scheme = "https"
u.Host = r.URL.Host
u.User = r.URL.User
Redirect(w, r, u.String())
})
}
Expand All @@ -92,40 +103,53 @@ func RequireHost(host string, handler http.Handler) http.Handler {
return whmux.Host{
host: handler,
"*": http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
u, err := url.ParseRequestURI(r.RequestURI)
u, err := FullURL(r)
if err != nil {
wherr.Handle(w, r, err)
return
}
u.Scheme = r.URL.Scheme
u.Host = host
u.User = r.URL.User
Redirect(w, r, u.String())
})}
}

func addTrailingSlash(w http.ResponseWriter, r *http.Request, h http.Handler) {
u, err := FullURL(r)
if err != nil {
wherr.Handle(w, r, err)
return
}

if strings.HasSuffix(u.Path, "/") {
h.ServeHTTP(w, r)
return
}

u.Path += "/"
Redirect(w, r, u.String())
}

// RequireTrailingSlash makes sure all handled paths have a trailing slash.
// This helps with relative URLs for other resources.
func RequireTrailingSlash(h http.Handler) http.Handler {
return whroute.HandlerFunc(h,
func(w http.ResponseWriter, r *http.Request) {
if strings.HasSuffix(r.URL.Path, "/") {
if r.URL.Path != "/" && strings.HasSuffix(r.URL.Path, "/") {
h.ServeHTTP(w, r)
return
}

u, err := url.ParseRequestURI(r.RequestURI)
if err != nil {
wherr.Handle(w, r, err)
return
}
addTrailingSlash(w, r, h)
})
}

if strings.HasSuffix(u.Path, "/") {
h.ServeHTTP(w, r)
return
}
func RequireNextSlash(h http.Handler) http.Handler {
return whroute.HandlerFunc(h, func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" && r.URL.Path != "" {
h.ServeHTTP(w, r)
return
}

u.Path += "/"
Redirect(w, r, u.String())
})
addTrailingSlash(w, r, h)
})
}

0 comments on commit cd8c17f

Please sign in to comment.