Validate target id

This commit is contained in:
Viktor Liu
2026-02-08 23:42:07 +08:00
parent 1c8f92a96f
commit 7f11e3205d
2 changed files with 41 additions and 0 deletions

View File

@@ -110,6 +110,10 @@ func (m *managerImpl) CreateReverseProxy(ctx context.Context, accountID, userID
return status.Errorf(status.AlreadyExists, "reverse proxy with domain %s already exists", reverseProxy.Domain)
}
if err = validateTargetReferences(ctx, transaction, accountID, reverseProxy.Targets); err != nil {
return err
}
if err = transaction.CreateReverseProxy(ctx, reverseProxy); err != nil {
return fmt.Errorf("failed to create reverse proxy: %w", err)
}
@@ -181,6 +185,10 @@ func (m *managerImpl) UpdateReverseProxy(ctx context.Context, accountID, userID
reverseProxy.SessionPrivateKey = existingReverseProxy.SessionPrivateKey
reverseProxy.SessionPublicKey = existingReverseProxy.SessionPublicKey
if err = validateTargetReferences(ctx, transaction, accountID, reverseProxy.Targets); err != nil {
return err
}
if err = transaction.UpdateReverseProxy(ctx, reverseProxy); err != nil {
return fmt.Errorf("update reverse proxy: %w", err)
}
@@ -208,6 +216,29 @@ func (m *managerImpl) UpdateReverseProxy(ctx context.Context, accountID, userID
return reverseProxy, nil
}
// validateTargetReferences checks that all target IDs reference existing peers or resources in the account.
func validateTargetReferences(ctx context.Context, transaction store.Store, accountID string, targets []reverseproxy.Target) error {
for _, target := range targets {
switch target.TargetType {
case reverseproxy.TargetTypePeer:
if _, err := transaction.GetPeerByID(ctx, store.LockingStrengthShare, accountID, target.TargetId); err != nil {
if sErr, ok := status.FromError(err); ok && sErr.Type() == status.NotFound {
return status.Errorf(status.InvalidArgument, "peer target %q not found in account", target.TargetId)
}
return fmt.Errorf("look up peer target %q: %w", target.TargetId, err)
}
case reverseproxy.TargetTypeResource:
if _, err := transaction.GetNetworkResourceByID(ctx, store.LockingStrengthShare, accountID, target.TargetId); err != nil {
if sErr, ok := status.FromError(err); ok && sErr.Type() == status.NotFound {
return status.Errorf(status.InvalidArgument, "resource target %q not found in account", target.TargetId)
}
return fmt.Errorf("look up resource target %q: %w", target.TargetId, err)
}
}
}
return nil
}
func (m *managerImpl) DeleteReverseProxy(ctx context.Context, accountID, userID, reverseProxyID string) error {
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, modules.Services, operations.Delete)
if err != nil {

View File

@@ -2,6 +2,7 @@ package reverseproxy
import (
"errors"
"fmt"
"net"
"net/url"
"strconv"
@@ -328,6 +329,15 @@ func (r *ReverseProxy) Validate() error {
return errors.New("at least one target is required")
}
for i, target := range r.Targets {
if target.TargetType != TargetTypePeer && target.TargetType != TargetTypeResource {
return fmt.Errorf("target %d has invalid target_type %q, must be %q or %q", i, target.TargetType, TargetTypePeer, TargetTypeResource)
}
if target.TargetId == "" {
return fmt.Errorf("target %d has empty target_id", i)
}
}
return nil
}