gpm/router/router.go

152 lines
3.3 KiB
Go

package router
import (
"encoding/json"
"io"
"net/http"
"time"
"go.jolheiser.com/gpm/database"
"go.jolheiser.com/gpm/go-gpm"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"go.jolheiser.com/beaver"
)
var Version = "develop"
func New(token 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(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(db *database.Database) func(res http.ResponseWriter, _ *http.Request) {
return func(res http.ResponseWriter, _ *http.Request) {
pkgs, err := db.Packages()
if err != nil {
beaver.Error(err)
return
}
status, err := json.Marshal(gpm.Info{
Version: Version,
NumPackages: len(pkgs),
Packages: pkgs,
})
if err != nil {
res.WriteHeader(http.StatusInternalServerError)
_, _ = res.Write([]byte("{}"))
return
}
_, _ = res.Write(status)
}
}
func getPackage(db *database.Database) func(http.ResponseWriter, *http.Request) {
return func(res http.ResponseWriter, req *http.Request) {
name := chi.URLParam(req, "name")
pkg, err := db.PackageJSON(name)
if err != nil {
res.WriteHeader(http.StatusNotFound)
_, _ = res.Write([]byte("{}"))
return
}
_, _ = res.Write(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
}
data, err := io.ReadAll(req.Body)
if err != nil {
res.WriteHeader(http.StatusBadRequest)
return
}
defer req.Body.Close()
var pkg gpm.Package
if err := json.Unmarshal(data, &pkg); err != nil {
res.WriteHeader(http.StatusBadRequest)
return
}
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
}
data, err := io.ReadAll(req.Body)
if err != nil {
res.WriteHeader(http.StatusBadRequest)
return
}
defer req.Body.Close()
var pkg gpm.Package
if err := json.Unmarshal(data, &pkg); err != nil {
res.WriteHeader(http.StatusBadRequest)
return
}
if err := db.RemovePackage(pkg.Name); err != nil {
res.WriteHeader(http.StatusInternalServerError)
return
}
res.WriteHeader(http.StatusOK)
}
}