130 lines
2.9 KiB
Go
130 lines
2.9 KiB
Go
|
package router
|
||
|
|
||
|
import (
|
||
|
"net/http"
|
||
|
"time"
|
||
|
|
||
|
"go.jolheiser.com/gpm"
|
||
|
"go.jolheiser.com/gpm/internal/database"
|
||
|
|
||
|
"github.com/go-chi/chi/v5"
|
||
|
"github.com/go-chi/chi/v5/middleware"
|
||
|
"github.com/go-chi/render"
|
||
|
"github.com/rs/zerolog/log"
|
||
|
)
|
||
|
|
||
|
func New(token, version string, db *database.Database) *chi.Mux {
|
||
|
r := chi.NewRouter()
|
||
|
r.Use(middleware.RedirectSlashes)
|
||
|
r.Use(middleware.Recoverer)
|
||
|
r.Use(middleware.Timeout(30 * time.Second))
|
||
|
|
||
|
r.Get("/", handleHome(version, db))
|
||
|
r.Post("/", addUpdatePackage(db, token))
|
||
|
r.Patch("/", addUpdatePackage(db, token))
|
||
|
r.Delete("/", removePackage(db, token))
|
||
|
r.Get("/{name}", getPackage(db))
|
||
|
|
||
|
return r
|
||
|
}
|
||
|
|
||
|
func handleHome(version string, db *database.Database) func(http.ResponseWriter, *http.Request) {
|
||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||
|
pkgs, err := db.Packages()
|
||
|
if err != nil {
|
||
|
log.Err(err).Msg("")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
render.JSON(w, r, gpm.Info{
|
||
|
Version: version,
|
||
|
NumPackages: len(pkgs),
|
||
|
Packages: pkgs,
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func getPackage(db *database.Database) func(http.ResponseWriter, *http.Request) {
|
||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||
|
name := chi.URLParam(r, "name")
|
||
|
|
||
|
pkg, err := db.Package(name)
|
||
|
if err != nil {
|
||
|
w.WriteHeader(http.StatusNotFound)
|
||
|
render.JSON(w, r, struct{}{})
|
||
|
return
|
||
|
}
|
||
|
|
||
|
render.JSON(w, r, pkg)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func addUpdatePackage(db *database.Database, token string) func(http.ResponseWriter, *http.Request) {
|
||
|
return func(res http.ResponseWriter, req *http.Request) {
|
||
|
if req.Header.Get(gpm.TokenHeader) != token {
|
||
|
res.WriteHeader(http.StatusUnauthorized)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
var pkg gpm.Package
|
||
|
if err := render.DecodeJSON(req.Body, &pkg); err != nil {
|
||
|
res.WriteHeader(http.StatusBadRequest)
|
||
|
return
|
||
|
}
|
||
|
defer req.Body.Close()
|
||
|
|
||
|
exists, err := db.PackageJSON(pkg.Name)
|
||
|
if err != nil {
|
||
|
res.WriteHeader(http.StatusInternalServerError)
|
||
|
return
|
||
|
}
|
||
|
switch req.Method {
|
||
|
case http.MethodPost:
|
||
|
if exists != nil {
|
||
|
res.WriteHeader(http.StatusConflict)
|
||
|
return
|
||
|
}
|
||
|
case http.MethodPatch:
|
||
|
if exists == nil {
|
||
|
res.WriteHeader(http.StatusNotFound)
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if err := db.PutPackage(pkg); err != nil {
|
||
|
res.WriteHeader(http.StatusInternalServerError)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
switch req.Method {
|
||
|
case http.MethodPost:
|
||
|
res.WriteHeader(http.StatusCreated)
|
||
|
case http.MethodPatch:
|
||
|
res.WriteHeader(http.StatusOK)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func removePackage(db *database.Database, token string) func(http.ResponseWriter, *http.Request) {
|
||
|
return func(res http.ResponseWriter, req *http.Request) {
|
||
|
if req.Header.Get(gpm.TokenHeader) != token {
|
||
|
res.WriteHeader(http.StatusUnauthorized)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
var pkg gpm.Package
|
||
|
if err := render.DecodeJSON(req.Body, &pkg); err != nil {
|
||
|
res.WriteHeader(http.StatusBadRequest)
|
||
|
return
|
||
|
}
|
||
|
defer req.Body.Close()
|
||
|
|
||
|
if err := db.RemovePackage(pkg.Name); err != nil {
|
||
|
res.WriteHeader(http.StatusInternalServerError)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
res.WriteHeader(http.StatusOK)
|
||
|
}
|
||
|
}
|