113 lines
2.5 KiB
Go
113 lines
2.5 KiB
Go
|
package app
|
||
|
|
||
|
import (
|
||
|
"net"
|
||
|
"net/http"
|
||
|
|
||
|
"forge.cadoles.com/arcad/edge/pkg/app"
|
||
|
"github.com/go-chi/chi/v5"
|
||
|
"github.com/pkg/errors"
|
||
|
"gitlab.com/wpetit/goweb/api"
|
||
|
"gitlab.com/wpetit/goweb/logger"
|
||
|
)
|
||
|
|
||
|
type MountFunc func(r chi.Router)
|
||
|
|
||
|
type Handler struct {
|
||
|
repo Repository
|
||
|
}
|
||
|
|
||
|
func (h *Handler) serveApps(w http.ResponseWriter, r *http.Request) {
|
||
|
manifests, err := h.repo.List(r.Context())
|
||
|
if err != nil {
|
||
|
logger.Error(r.Context(), "could not retrieve app manifest", logger.E(errors.WithStack(err)))
|
||
|
api.ErrorResponse(w, http.StatusInternalServerError, api.ErrCodeUnknownError, nil)
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
api.DataResponse(w, http.StatusOK, struct {
|
||
|
Manifests []*app.Manifest `json:"manifests"`
|
||
|
}{
|
||
|
Manifests: manifests,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func (h *Handler) serveApp(w http.ResponseWriter, r *http.Request) {
|
||
|
appID := app.ID(chi.URLParam(r, "appID"))
|
||
|
|
||
|
manifest, err := h.repo.Get(r.Context(), appID)
|
||
|
if err != nil {
|
||
|
if errors.Is(err, ErrNotFound) {
|
||
|
api.ErrorResponse(w, http.StatusNotFound, api.ErrCodeNotFound, nil)
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
logger.Error(r.Context(), "could not retrieve app manifest", logger.E(errors.WithStack(err)))
|
||
|
api.ErrorResponse(w, http.StatusInternalServerError, api.ErrCodeUnknownError, nil)
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
api.DataResponse(w, http.StatusOK, struct {
|
||
|
Manifest *app.Manifest `json:"manifest"`
|
||
|
}{
|
||
|
Manifest: manifest,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
type serveAppURLRequest struct {
|
||
|
From string `json:"from,omitempty"`
|
||
|
}
|
||
|
|
||
|
func (h *Handler) serveAppURL(w http.ResponseWriter, r *http.Request) {
|
||
|
ctx := r.Context()
|
||
|
|
||
|
req := &serveAppURLRequest{}
|
||
|
if ok := api.Bind(w, r, req); !ok {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
appID := app.ID(chi.URLParam(r, "appID"))
|
||
|
|
||
|
from := req.From
|
||
|
if from == "" {
|
||
|
host, _, err := net.SplitHostPort(r.RemoteAddr)
|
||
|
if err != nil {
|
||
|
logger.Warn(ctx, "could not split remote address", logger.E(errors.WithStack(err)))
|
||
|
} else {
|
||
|
from = host
|
||
|
}
|
||
|
}
|
||
|
|
||
|
url, err := h.repo.GetURL(ctx, appID, from)
|
||
|
if err != nil {
|
||
|
if errors.Is(err, ErrNotFound) {
|
||
|
api.ErrorResponse(w, http.StatusNotFound, api.ErrCodeNotFound, nil)
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
logger.Error(r.Context(), "could not retrieve app url", logger.E(errors.WithStack(err)))
|
||
|
api.ErrorResponse(w, http.StatusInternalServerError, api.ErrCodeUnknownError, nil)
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
api.DataResponse(w, http.StatusOK, struct {
|
||
|
URL string `json:"url"`
|
||
|
}{
|
||
|
URL: url,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func Mount(repository Repository) MountFunc {
|
||
|
handler := &Handler{repository}
|
||
|
return func(r chi.Router) {
|
||
|
r.Get("/api/v1/apps", handler.serveApps)
|
||
|
r.Get("/api/v1/apps/{appID}", handler.serveApp)
|
||
|
r.Post("/api/v1/apps/{appID}/url", handler.serveAppURL)
|
||
|
}
|
||
|
}
|