internal/httputil: use error structs for http errors (#159)

The existing implementation used a ErrorResponse method to propogate
and create http error messages. Since we added functionality to
troubleshoot, signout, and do other tasks following an http error
it's useful to use Error struct in place of method arguments.

This fixes #157 where a troubleshooting links were appearing on pages
that it didn't make sense on (e.g. pages without valid sessions).
This commit is contained in:
Bobby DeSimone 2019-06-03 20:00:37 -07:00 committed by GitHub
parent 14403ce388
commit bade9f50e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 244 additions and 133 deletions

View file

@ -32,9 +32,9 @@ func SetHeaders(securityHeaders map[string]string) func(next http.Handler) http.
func ValidateClientSecret(sharedSecret string) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
httputil.ErrorResponse(w, r, err.Error(), http.StatusBadRequest)
if err := r.ParseForm(); err != nil {
httpErr := &httputil.Error{Message: err.Error(), Code: http.StatusBadRequest}
httputil.ErrorResponse(w, r, httpErr)
return
}
clientSecret := r.Form.Get("shared_secret")
@ -44,7 +44,7 @@ func ValidateClientSecret(sharedSecret string) func(next http.Handler) http.Hand
}
if clientSecret != sharedSecret {
httputil.ErrorResponse(w, r, "Invalid client secret", http.StatusUnauthorized)
httputil.ErrorResponse(w, r, &httputil.Error{Code: http.StatusInternalServerError})
return
}
next.ServeHTTP(w, r)
@ -59,16 +59,25 @@ func ValidateRedirectURI(rootDomain *url.URL) func(next http.Handler) http.Handl
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
httputil.ErrorResponse(w, r, err.Error(), http.StatusBadRequest)
httpErr := &httputil.Error{
Message: err.Error(),
Code: http.StatusBadRequest}
httputil.ErrorResponse(w, r, httpErr)
return
}
redirectURI, err := url.Parse(r.Form.Get("redirect_uri"))
if err != nil {
httputil.ErrorResponse(w, r, err.Error(), http.StatusBadRequest)
httpErr := &httputil.Error{
Message: err.Error(),
Code: http.StatusBadRequest}
httputil.ErrorResponse(w, r, httpErr)
return
}
if !SameDomain(redirectURI, rootDomain) {
httputil.ErrorResponse(w, r, "Invalid redirect parameter", http.StatusBadRequest)
httpErr := &httputil.Error{
Message: "Invalid redirect parameter",
Code: http.StatusBadRequest}
httputil.ErrorResponse(w, r, httpErr)
return
}
next.ServeHTTP(w, r)
@ -96,14 +105,18 @@ func ValidateSignature(sharedSecret string) func(next http.Handler) http.Handler
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
httputil.ErrorResponse(w, r, err.Error(), http.StatusBadRequest)
httpErr := &httputil.Error{Message: err.Error(), Code: http.StatusBadRequest}
httputil.ErrorResponse(w, r, httpErr)
return
}
redirectURI := r.Form.Get("redirect_uri")
sigVal := r.Form.Get("sig")
timestamp := r.Form.Get("ts")
if !ValidSignature(redirectURI, sigVal, timestamp, sharedSecret) {
httputil.ErrorResponse(w, r, "Cross service signature failed to validate", http.StatusUnauthorized)
httpErr := &httputil.Error{
Message: "Cross service signature failed to validate",
Code: http.StatusUnauthorized}
httputil.ErrorResponse(w, r, httpErr)
return
}
@ -117,7 +130,7 @@ func ValidateHost(validHost func(host string) bool) func(next http.Handler) http
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !validHost(r.Host) {
httputil.ErrorResponse(w, r, "Unknown route", http.StatusNotFound)
httputil.ErrorResponse(w, r, &httputil.Error{Code: http.StatusNotFound})
return
}
next.ServeHTTP(w, r)