2023-04-18 17:57:16 +02:00
|
|
|
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 {
|
2023-10-19 21:47:09 +02:00
|
|
|
logger.Error(r.Context(), "could not retrieve app manifest", logger.CapturedE(errors.WithStack(err)))
|
2023-04-18 17:57:16 +02:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-10-19 21:47:09 +02:00
|
|
|
logger.Error(r.Context(), "could not retrieve app manifest", logger.CapturedE(errors.WithStack(err)))
|
2023-04-18 17:57:16 +02:00
|
|
|
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 == "" {
|
2023-04-21 20:01:43 +02:00
|
|
|
from = retrieveRemoteAddr(r)
|
2023-04-18 17:57:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-10-19 21:47:09 +02:00
|
|
|
logger.Error(r.Context(), "could not retrieve app url", logger.CapturedE(errors.WithStack(err)))
|
2023-04-18 17:57:16 +02:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
2023-04-21 20:01:43 +02:00
|
|
|
|
|
|
|
func retrieveRemoteAddr(r *http.Request) string {
|
|
|
|
host, _, err := net.SplitHostPort(r.RemoteAddr)
|
|
|
|
if err != nil {
|
|
|
|
host = r.RemoteAddr
|
|
|
|
}
|
|
|
|
|
|
|
|
return host
|
|
|
|
}
|