From 964bdc236924b449b4a40b21fe294e841e6cff70 Mon Sep 17 00:00:00 2001 From: PrasunaEnumarthy Date: Mon, 6 Apr 2026 01:20:03 +0530 Subject: [PATCH 1/4] fix(webhook): normalize endpoint URL before validation Signed-off-by: PrasunaEnumarthy --- cmd/harbor/root/webhook/create.go | 4 +++- cmd/harbor/root/webhook/edit.go | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cmd/harbor/root/webhook/create.go b/cmd/harbor/root/webhook/create.go index 5a7371aa8..6081a8a50 100644 --- a/cmd/harbor/root/webhook/create.go +++ b/cmd/harbor/root/webhook/create.go @@ -69,10 +69,12 @@ or leave them out and be guided through an interactive prompt to input each fiel opts.NotifyType != "" && len(opts.EventType) != 0 && opts.EndpointURL != "" { - err = utils.ValidateURL(opts.EndpointURL) + formattedURL := utils.FormatUrl(opts.EndpointURL) + err = utils.ValidateURL(formattedURL) if err != nil { return err } + opts.EndpointURL = formattedURL err = api.CreateWebhook(&opts) } else { err = createWebhookView(createView) diff --git a/cmd/harbor/root/webhook/edit.go b/cmd/harbor/root/webhook/edit.go index 4ba716006..8d459efdd 100644 --- a/cmd/harbor/root/webhook/edit.go +++ b/cmd/harbor/root/webhook/edit.go @@ -85,10 +85,13 @@ or leave them out and use the interactive prompt to select and update a webhook. opts.NotifyType != "" && len(opts.EventType) != 0 && opts.EndpointURL != "" { - if err := utils.ValidateURL(opts.EndpointURL); err != nil { + formattedURL := utils.FormatUrl(opts.EndpointURL) + if err := utils.ValidateURL(formattedURL); err != nil { return err } + opts.EndpointURL = formattedURL err = api.UpdateWebhook(&opts) + } else { err = editWebhookView(editView) } From ede18edbf736790573e6b25674a72f960089ead7 Mon Sep 17 00:00:00 2001 From: PrasunaEnumarthy Date: Wed, 8 Apr 2026 08:12:14 +0530 Subject: [PATCH 2/4] test(webhook): add coverage for endpoint URL normalization Signed-off-by: PrasunaEnumarthy --- cmd/harbor/root/webhook/edit.go | 1 - cmd/harbor/root/webhook/webhook_test.go | 50 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 cmd/harbor/root/webhook/webhook_test.go diff --git a/cmd/harbor/root/webhook/edit.go b/cmd/harbor/root/webhook/edit.go index 8d459efdd..2dedd164f 100644 --- a/cmd/harbor/root/webhook/edit.go +++ b/cmd/harbor/root/webhook/edit.go @@ -91,7 +91,6 @@ or leave them out and use the interactive prompt to select and update a webhook. } opts.EndpointURL = formattedURL err = api.UpdateWebhook(&opts) - } else { err = editWebhookView(editView) } diff --git a/cmd/harbor/root/webhook/webhook_test.go b/cmd/harbor/root/webhook/webhook_test.go new file mode 100644 index 000000000..966343897 --- /dev/null +++ b/cmd/harbor/root/webhook/webhook_test.go @@ -0,0 +1,50 @@ +package webhook + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCreateWebhookCmd_NormalizesEndpointURLBeforeValidation(t *testing.T) { + cmd := CreateWebhookCmd() + + var buf bytes.Buffer + cmd.SetOut(&buf) + cmd.SetErr(&buf) + cmd.SetArgs([]string{ + "my-webhook", + "--project", "my-project", + "--notify-type", "http", + "--event-type", "PUSH_ARTIFACT", + "--endpoint-url", "example.com/webhook", + }) + + err := cmd.Execute() + assert.Error(t, err) + assert.Contains(t, err.Error(), "failed to create webhook") + assert.NotContains(t, err.Error(), "invalid URL format") + assert.NotContains(t, err.Error(), "invalid host") +} + +func TestEditWebhookCmd_NormalizesEndpointURLBeforeValidation(t *testing.T) { + cmd := EditWebhookCmd() + + var buf bytes.Buffer + cmd.SetOut(&buf) + cmd.SetErr(&buf) + cmd.SetArgs([]string{ + "--project", "my-project", + "--webhook-id", "1", + "--notify-type", "http", + "--event-type", "PUSH_ARTIFACT", + "--endpoint-url", "example.com/webhook", + }) + + err := cmd.Execute() + assert.Error(t, err) + assert.Contains(t, err.Error(), "failed to edit webhook") + assert.NotContains(t, err.Error(), "invalid URL format") + assert.NotContains(t, err.Error(), "invalid host") +} From 531c01377b9c520de3994a5bbfe30e64c9b3590c Mon Sep 17 00:00:00 2001 From: PrasunaEnumarthy Date: Wed, 8 Apr 2026 08:27:51 +0530 Subject: [PATCH 3/4] test(webhook): add header to webhook tests Signed-off-by: PrasunaEnumarthy --- cmd/harbor/root/webhook/webhook_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cmd/harbor/root/webhook/webhook_test.go b/cmd/harbor/root/webhook/webhook_test.go index 966343897..9494cfef0 100644 --- a/cmd/harbor/root/webhook/webhook_test.go +++ b/cmd/harbor/root/webhook/webhook_test.go @@ -1,3 +1,16 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package webhook import ( From 4afeb5d583606fd0bdbe1692e9e88605b4b5e9ac Mon Sep 17 00:00:00 2001 From: PrasunaEnumarthy Date: Wed, 8 Apr 2026 15:27:09 +0530 Subject: [PATCH 4/4] test(webhook): cover invalid endpoint validation path Signed-off-by: PrasunaEnumarthy --- cmd/harbor/root/webhook/webhook_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/cmd/harbor/root/webhook/webhook_test.go b/cmd/harbor/root/webhook/webhook_test.go index 9494cfef0..8e6d7de95 100644 --- a/cmd/harbor/root/webhook/webhook_test.go +++ b/cmd/harbor/root/webhook/webhook_test.go @@ -61,3 +61,22 @@ func TestEditWebhookCmd_NormalizesEndpointURLBeforeValidation(t *testing.T) { assert.NotContains(t, err.Error(), "invalid URL format") assert.NotContains(t, err.Error(), "invalid host") } + +func TestEditWebhookCmd_InvalidEndpointURLReturnsValidationError(t *testing.T) { + cmd := EditWebhookCmd() + + var buf bytes.Buffer + cmd.SetOut(&buf) + cmd.SetErr(&buf) + cmd.SetArgs([]string{ + "--project", "my-project", + "--webhook-id", "1", + "--notify-type", "http", + "--event-type", "PUSH_ARTIFACT", + "--endpoint-url", "http://", + }) + + err := cmd.Execute() + assert.Error(t, err) + assert.Contains(t, err.Error(), "URL must contain a valid host") +}