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