235 lines
5.4 KiB
Go
235 lines
5.4 KiB
Go
package admin
|
|
|
|
import (
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"forge.cadoles.com/cadoles/bouncer/internal/store"
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/pkg/errors"
|
|
"gitlab.com/wpetit/goweb/api"
|
|
"gitlab.com/wpetit/goweb/logger"
|
|
)
|
|
|
|
type QueryProxyResponse struct {
|
|
Proxies []*store.ProxyHeader `json:"proxies"`
|
|
}
|
|
|
|
func (s *Server) queryProxy(w http.ResponseWriter, r *http.Request) {
|
|
limit, ok := getIntQueryParam(w, r, "limit", 10)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
offset, ok := getIntQueryParam(w, r, "offset", 0)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
options := []store.QueryProxyOptionFunc{
|
|
store.WithProxyQueryLimit(int(limit)),
|
|
store.WithProxyQueryOffset(int(offset)),
|
|
}
|
|
|
|
ids, ok := getStringableSliceValues[store.ProxyID](w, r, "ids", nil)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
if ids != nil {
|
|
options = append(options, store.WithProxyQueryIDs(ids...))
|
|
}
|
|
|
|
ctx := r.Context()
|
|
|
|
proxies, err := s.proxyRepository.QueryProxy(
|
|
ctx,
|
|
options...,
|
|
)
|
|
if err != nil {
|
|
logger.Error(ctx, "could not list proxies", logger.E(errors.WithStack(err)))
|
|
api.ErrorResponse(w, http.StatusInternalServerError, api.ErrCodeUnknownError, nil)
|
|
|
|
return
|
|
}
|
|
|
|
api.DataResponse(w, http.StatusOK, QueryProxyResponse{
|
|
Proxies: proxies,
|
|
})
|
|
}
|
|
|
|
type GetProxyResponse struct {
|
|
Proxy *store.Proxy `json:"proxy"`
|
|
}
|
|
|
|
func (s *Server) getProxy(w http.ResponseWriter, r *http.Request) {
|
|
proxyID, ok := getProxyID(w, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
ctx := r.Context()
|
|
|
|
proxy, err := s.proxyRepository.GetProxy(ctx, proxyID)
|
|
if err != nil {
|
|
if errors.Is(err, store.ErrNotFound) {
|
|
api.ErrorResponse(w, http.StatusNotFound, api.ErrCodeNotFound, nil)
|
|
|
|
return
|
|
}
|
|
|
|
logger.Error(ctx, "could not get proxy", logger.E(errors.WithStack(err)))
|
|
api.ErrorResponse(w, http.StatusInternalServerError, api.ErrCodeUnknownError, nil)
|
|
|
|
return
|
|
}
|
|
|
|
api.DataResponse(w, http.StatusOK, GetProxyResponse{
|
|
Proxy: proxy,
|
|
})
|
|
}
|
|
|
|
type DeleteProxyResponse struct {
|
|
ProxyID store.ProxyID `json:"proxyId"`
|
|
}
|
|
|
|
func (s *Server) deleteProxy(w http.ResponseWriter, r *http.Request) {
|
|
proxyID, ok := getProxyID(w, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
ctx := r.Context()
|
|
|
|
if err := s.proxyRepository.DeleteProxy(ctx, proxyID); err != nil {
|
|
if errors.Is(err, store.ErrNotFound) {
|
|
api.ErrorResponse(w, http.StatusNotFound, api.ErrCodeNotFound, nil)
|
|
|
|
return
|
|
}
|
|
|
|
logger.Error(ctx, "could not delete proxy", logger.E(errors.WithStack(err)))
|
|
api.ErrorResponse(w, http.StatusInternalServerError, api.ErrCodeUnknownError, nil)
|
|
|
|
return
|
|
}
|
|
|
|
api.DataResponse(w, http.StatusOK, DeleteProxyResponse{
|
|
ProxyID: proxyID,
|
|
})
|
|
}
|
|
|
|
type CreateProxyRequest struct {
|
|
To string `json:"to" validate:"required"`
|
|
From []string `json:"from" validate:"required"`
|
|
}
|
|
|
|
type CreateProxyResponse struct {
|
|
Proxy *store.Proxy `json:"proxy"`
|
|
}
|
|
|
|
func (s *Server) createProxy(w http.ResponseWriter, r *http.Request) {
|
|
ctx := r.Context()
|
|
|
|
createProxyReq := &CreateProxyRequest{}
|
|
if ok := api.Bind(w, r, createProxyReq); !ok {
|
|
return
|
|
}
|
|
|
|
to, err := url.Parse(createProxyReq.To)
|
|
if err != nil {
|
|
logger.Error(r.Context(), "could not parse to parameter", logger.E(errors.WithStack(err)))
|
|
api.ErrorResponse(w, http.StatusBadRequest, api.ErrCodeMalformedRequest, nil)
|
|
|
|
return
|
|
}
|
|
|
|
proxy, err := s.proxyRepository.CreateProxy(ctx, to, createProxyReq.From...)
|
|
if err != nil {
|
|
logger.Error(ctx, "could not update agent", logger.E(errors.WithStack(err)))
|
|
api.ErrorResponse(w, http.StatusInternalServerError, api.ErrCodeUnknownError, nil)
|
|
|
|
return
|
|
}
|
|
|
|
api.DataResponse(w, http.StatusOK, struct {
|
|
Proxy *store.Proxy `json:"proxy"`
|
|
}{
|
|
Proxy: proxy,
|
|
})
|
|
}
|
|
|
|
type UpdateProxyRequest struct{}
|
|
|
|
func (s *Server) updateProxy(w http.ResponseWriter, r *http.Request) {
|
|
}
|
|
|
|
func getProxyID(w http.ResponseWriter, r *http.Request) (store.ProxyID, bool) {
|
|
rawProxyID := chi.URLParam(r, "proxyID")
|
|
|
|
proxyID, err := store.ParseProxyID(rawProxyID)
|
|
if err != nil {
|
|
logger.Error(r.Context(), "could not parse proxy id", logger.E(errors.WithStack(err)))
|
|
api.ErrorResponse(w, http.StatusBadRequest, api.ErrCodeMalformedRequest, nil)
|
|
|
|
return "", false
|
|
}
|
|
|
|
return proxyID, true
|
|
}
|
|
|
|
func getIntQueryParam(w http.ResponseWriter, r *http.Request, param string, defaultValue int64) (int64, bool) {
|
|
rawValue := r.URL.Query().Get(param)
|
|
if rawValue != "" {
|
|
value, err := strconv.ParseInt(rawValue, 10, 64)
|
|
if err != nil {
|
|
logger.Error(r.Context(), "could not parse int param", logger.F("param", param), logger.E(errors.WithStack(err)))
|
|
api.ErrorResponse(w, http.StatusBadRequest, api.ErrCodeMalformedRequest, nil)
|
|
|
|
return 0, false
|
|
}
|
|
|
|
return value, true
|
|
}
|
|
|
|
return defaultValue, true
|
|
}
|
|
|
|
func getStringSliceValues(w http.ResponseWriter, r *http.Request, param string, defaultValue []string) ([]string, bool) {
|
|
rawValue := r.URL.Query().Get(param)
|
|
if rawValue != "" {
|
|
values := strings.Split(rawValue, ",")
|
|
|
|
return values, true
|
|
}
|
|
|
|
return defaultValue, true
|
|
}
|
|
|
|
func getStringableSliceValues[T ~string](w http.ResponseWriter, r *http.Request, param string, defaultValue []T) ([]T, bool) {
|
|
rawValue := r.URL.Query().Get(param)
|
|
|
|
if rawValue != "" {
|
|
rawValues := strings.Split(rawValue, ",")
|
|
ids := make([]T, 0, len(rawValues))
|
|
|
|
for _, rv := range rawValues {
|
|
id, err := store.ParseID[T](rv)
|
|
if err != nil {
|
|
logger.Error(r.Context(), "could not parse ids slice param", logger.F("param", param), logger.E(errors.WithStack(err)))
|
|
api.ErrorResponse(w, http.StatusBadRequest, api.ErrCodeMalformedRequest, nil)
|
|
|
|
return nil, false
|
|
}
|
|
|
|
ids = append(ids, id)
|
|
}
|
|
|
|
return ids, true
|
|
}
|
|
|
|
return defaultValue, true
|
|
}
|