From f1dc5ece9206badfabe42fde7b52379c2ca97bad Mon Sep 17 00:00:00 2001 From: shiro8613 Date: Sun, 12 Jan 2025 22:48:36 +0900 Subject: [PATCH 1/5] Add: a CustomHeaders field of type map[string]string to RemoteQueryConfiguration for custom headers in remote requests. --- config/config.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/config.go b/config/config.go index 861156cb..0a2a8826 100644 --- a/config/config.go +++ b/config/config.go @@ -119,6 +119,12 @@ type RemoteQueryConfiguration struct { // 50 servers is likely just as quick as two for 100 or one for 400, and will certainly // be less likely to cause performance issues on the Panel. BootServersPerPage int `default:"50" yaml:"boot_servers_per_page"` + + //When using services like Cloudflare Access to manage access to + //a specific system via an external authentication system, + //it is possible to add special headers to bypass authentication. + //The mentioned headers can be appended to queries sent from Wings to the panel. + CustomHeaders map[string]string `yaml:"custom_headers"` } // SystemConfiguration defines basic system configuration settings. From 1baf955221ca4faef890003255efcc73c90eb0b3 Mon Sep 17 00:00:00 2001 From: shiro8613 Date: Sun, 12 Jan 2025 22:49:38 +0900 Subject: [PATCH 2/5] Add: custom header processing --- remote/http.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/remote/http.go b/remote/http.go index 006a7f44..e6a93691 100644 --- a/remote/http.go +++ b/remote/http.go @@ -42,6 +42,7 @@ type client struct { tokenId string token string maxAttempts int + customHeaders map[string]string } // New returns a new HTTP request client that is used for making authenticated @@ -69,6 +70,13 @@ func WithCredentials(id, token string) ClientOption { } } +// WithCustomHeader sets custom headers to be used when making remote requests. +func WithCustomHeader(headers map[string]string) ClientOption { + return func(c *client) { + c.customHeaders = headers + } +} + // WithHttpClient sets the underlying HTTP client instance to use when making // requests to the Panel API. func WithHttpClient(httpClient *http.Client) ClientOption { @@ -110,6 +118,10 @@ func (c *client) requestOnce(ctx context.Context, method, path string, body io.R req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", fmt.Sprintf("Bearer %s.%s", c.tokenId, c.token)) + + for cHeaderKey, cHeaderValue := range c.customHeaders { + req.Header.Set(cHeaderKey, cHeaderValue) + } // Call all opts functions to allow modifying the request for _, o := range opts { From cb5482a7694d5833f138d5e7855b6159d8e29d4d Mon Sep 17 00:00:00 2001 From: shiro8613 Date: Sun, 12 Jan 2025 22:50:42 +0900 Subject: [PATCH 3/5] Add: custom header configuration to the remote client --- cmd/root.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/root.go b/cmd/root.go index 2d9ff64d..5013996d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -149,6 +149,7 @@ func rootCmdRun(cmd *cobra.Command, _ []string) { pclient := remote.New( config.Get().PanelLocation, remote.WithCredentials(config.Get().AuthenticationTokenId, config.Get().AuthenticationToken), + remote.WithCustomHeader(config.Get().RemoteQuery.CustomHeaders), remote.WithHttpClient(&http.Client{ Timeout: time.Second * time.Duration(config.Get().RemoteQuery.Timeout), }), From c92a797a732c0e93b3a1b702e8c4d9874d272d0a Mon Sep 17 00:00:00 2001 From: Quinten <67589015+QuintenQVD0@users.noreply.github.com> Date: Thu, 20 Nov 2025 18:55:20 +0100 Subject: [PATCH 4/5] WithCustomHeader -> WithCustomHeaders --- cmd/root.go | 2 +- remote/http.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index d4cc3af1..8acc73bd 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -153,7 +153,7 @@ func rootCmdRun(cmd *cobra.Command, _ []string) { pclient := remote.New( config.Get().PanelLocation, remote.WithCredentials(t.ID, t.Token), - remote.WithCustomHeader(config.Get().RemoteQuery.CustomHeaders), + remote.WithCustomHeaders(config.Get().RemoteQuery.CustomHeaders), remote.WithHttpClient(&http.Client{ Timeout: time.Second * time.Duration(config.Get().RemoteQuery.Timeout), }), diff --git a/remote/http.go b/remote/http.go index e6a93691..9e0c206a 100644 --- a/remote/http.go +++ b/remote/http.go @@ -70,8 +70,8 @@ func WithCredentials(id, token string) ClientOption { } } -// WithCustomHeader sets custom headers to be used when making remote requests. -func WithCustomHeader(headers map[string]string) ClientOption { +// WithCustomHeaders sets custom headers to be used when making remote requests. +func WithCustomHeaders(headers map[string]string) ClientOption { return func(c *client) { c.customHeaders = headers } From 8321a888ce44fca2c894a6be649ebe98e7a83a31 Mon Sep 17 00:00:00 2001 From: Quinten <67589015+QuintenQVD0@users.noreply.github.com> Date: Thu, 20 Nov 2025 19:02:36 +0100 Subject: [PATCH 5/5] use criticalHeaders --- remote/http.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/remote/http.go b/remote/http.go index 9e0c206a..855f697a 100644 --- a/remote/http.go +++ b/remote/http.go @@ -119,9 +119,18 @@ func (c *client) requestOnce(ctx context.Context, method, path string, body io.R req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", fmt.Sprintf("Bearer %s.%s", c.tokenId, c.token)) - for cHeaderKey, cHeaderValue := range c.customHeaders { - req.Header.Set(cHeaderKey, cHeaderValue) - } + // Apply custom headers, but prevent overriding critical headers + criticalHeaders := map[string]bool{ + "Authorization": true, + "User-Agent": true, + "Accept": true, + "Content-Type": true, + } + for key, value := range c.customHeaders { + if !criticalHeaders[key] { + req.Header.Set(key, value) + } + } // Call all opts functions to allow modifying the request for _, o := range opts {