You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
quartermaster/pkg/utils/utils.go

106 lines
2.6 KiB

package utils
import (
"fmt"
"log"
"net/http"
"strings"
"github.com/dustinpianalto/errors"
"github.com/dustinpianalto/quartermaster"
"github.com/dustinpianalto/quartermaster/internal/jwt"
"github.com/dustinpianalto/quartermaster/pkg/services"
"github.com/gorilla/mux"
)
func Mount(r *mux.Router, path string, handler http.Handler) {
r.PathPrefix(path).Handler(
http.StripPrefix(
strings.TrimSuffix(path, "/"),
handler,
),
)
}
type RootHandler func(*http.ResponseWriter, *http.Request) error
func (rh RootHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
err := rh(&w, r)
if err == nil {
return
}
log.Println(err)
e, ok := err.(*errors.Error)
if !ok {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
if errors.Is(errors.Permission, e) {
body := getErrorBody("Permission Denied")
w.WriteHeader(http.StatusForbidden)
w.Write(body)
}
if errors.Is(errors.Incorrect, e) && strings.Contains(string(e.Method), "login") {
body := getErrorBody("Invalid Login Credentials")
w.WriteHeader(http.StatusUnauthorized)
w.Write(body)
}
if errors.Is(errors.Incorrect, e) && strings.Contains(string(e.Method), "refresh") {
body := getErrorBody("Missing or Invalid Cookie")
w.WriteHeader(http.StatusUnauthorized)
w.Write(body)
}
if errors.Is(errors.Malformed, e) {
body := getErrorBody("Bad Request")
w.WriteHeader(http.StatusBadRequest)
w.Write(body)
}
if errors.Is(errors.Internal, e) {
body := getErrorBody("Internal Server Error")
w.WriteHeader(http.StatusInternalServerError)
w.Write(body)
}
if errors.Is(errors.Conflict, e) && strings.Contains(string(e.Method), "register") {
body := getErrorBody("User already exists")
w.WriteHeader(http.StatusConflict)
w.Write(body)
}
}
func getErrorBody(s string) []byte {
return []byte(fmt.Sprintf("{\"error\": \"%s\"}", s))
}
type authenticatedHandler func(*http.ResponseWriter, *http.Request, *quartermaster.User) error
func AuthenticationMiddleware(next authenticatedHandler) RootHandler {
const method = "utils/AuthenticationMiddleware"
return RootHandler(func(w *http.ResponseWriter, r *http.Request) error {
claims, err := jwt.AuthenticateJWTToken(r)
if err != nil {
return errors.E(method, errors.Permission, "invalid token", err)
}
u, err := services.UserService.User(claims.Username)
if err != nil {
return errors.E(method, errors.Permission, "user not found", err)
}
err = next(w, r, u)
if err != nil {
return errors.E(method, "error in handler", err)
}
return nil
})
}