feat(server): PUT /v1/portforward route to set ports forwarded (#2392)

This commit is contained in:
Rubyn Angelo Stark
2026-03-07 18:06:03 +01:00
committed by Quentin McGaw
parent 199ad77ec9
commit 724cd3a15e
10 changed files with 119 additions and 40 deletions
+2 -2
View File
@@ -15,7 +15,7 @@ func newHandler(ctx context.Context, logger Logger, logging bool,
authSettings auth.Settings,
buildInfo models.BuildInformation,
vpnLooper VPNLooper,
pfGetter PortForwardedGetter,
pf PortForwarding,
dnsLooper DNSLoop,
updaterLooper UpdaterLooper,
publicIPLooper PublicIPLoop,
@@ -29,7 +29,7 @@ func newHandler(ctx context.Context, logger Logger, logging bool,
dns := newDNSHandler(ctx, dnsLooper, logger)
updater := newUpdaterHandler(ctx, updaterLooper, logger)
publicip := newPublicIPHandler(publicIPLooper, logger)
portForward := newPortForwardHandler(ctx, pfGetter, logger)
portForward := newPortForwardHandler(ctx, pf, logger)
handler.v0 = newHandlerV0(ctx, logger, vpnLooper, dnsLooper, updaterLooper)
handler.v1 = newHandlerV1(logger, buildInfo, vpn, openvpn, dns, updater, publicip, portForward)
+2 -1
View File
@@ -21,8 +21,9 @@ type DNSLoop interface {
GetStatus() (status models.LoopStatus)
}
type PortForwardedGetter interface {
type PortForwarding interface {
GetPortsForwarded() (ports []uint16)
SetPortsForwarded(ports []uint16) (err error)
}
type PublicIPLoop interface {
@@ -156,6 +156,7 @@ var validRoutes = map[string]struct{}{ //nolint:gochecknoglobals
http.MethodPut + " /v1/updater/status": {},
http.MethodGet + " /v1/publicip/ip": {},
http.MethodGet + " /v1/portforward": {},
http.MethodPut + " /v1/portforward": {},
}
func (r Role) ToLinesNode() (node *gotree.Node) {
+26 -2
View File
@@ -3,11 +3,12 @@ package server
import (
"context"
"encoding/json"
"fmt"
"net/http"
)
func newPortForwardHandler(ctx context.Context,
portForward PortForwardedGetter, warner warner,
portForward PortForwarding, warner warner,
) http.Handler {
return &portForwardHandler{
ctx: ctx,
@@ -18,7 +19,7 @@ func newPortForwardHandler(ctx context.Context,
type portForwardHandler struct {
ctx context.Context //nolint:containedctx
portForward PortForwardedGetter
portForward PortForwarding
warner warner
}
@@ -26,6 +27,8 @@ func (h *portForwardHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
h.getPortForwarded(w)
case http.MethodPut:
h.setPortForwarded(w, r)
default:
errMethodNotSupported(w, r.Method)
}
@@ -50,3 +53,24 @@ func (h *portForwardHandler) getPortForwarded(w http.ResponseWriter) {
w.WriteHeader(http.StatusInternalServerError)
}
}
func (h *portForwardHandler) setPortForwarded(w http.ResponseWriter, r *http.Request) {
var data portsWrapper
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&data)
if err != nil {
h.warner.Warn(fmt.Sprintf("failed setting forwarded ports: %s", err))
http.Error(w, "failed setting forwarded ports", http.StatusBadRequest)
return
}
err = h.portForward.SetPortsForwarded(data.Ports)
if err != nil {
h.warner.Warn(fmt.Sprintf("failed setting forwarded ports: %s", err))
http.Error(w, "failed setting forwarded ports", http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
}
+2 -2
View File
@@ -14,7 +14,7 @@ import (
func New(ctx context.Context, settings settings.ControlServer, logger Logger,
buildInfo models.BuildInformation, openvpnLooper VPNLooper,
pfGetter PortForwardedGetter, dnsLooper DNSLoop,
pf PortForwarding, dnsLooper DNSLoop,
updaterLooper UpdaterLooper, publicIPLooper PublicIPLoop, storage Storage,
ipv6Supported bool) (
server *httpserver.Server, err error,
@@ -25,7 +25,7 @@ func New(ctx context.Context, settings settings.ControlServer, logger Logger,
}
handler, err := newHandler(ctx, logger, *settings.Log, authSettings, buildInfo,
openvpnLooper, pfGetter, dnsLooper, updaterLooper, publicIPLooper,
openvpnLooper, pf, dnsLooper, updaterLooper, publicIPLooper,
storage, ipv6Supported)
if err != nil {
return nil, fmt.Errorf("creating handler: %w", err)