From 9ebd517c7ebeccb1069e84736e62728d247c7d33 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Thu, 10 Jun 2021 22:16:05 +0800 Subject: [PATCH] Add validation for destination namespace when creating/updating replication policy Add validation for destination namespace when creating/updating replication policy Signed-off-by: Wenkai Yin --- src/controller/replication/model/model.go | 11 ++++++++++- src/lib/patterns.go | 4 +++- src/lib/patterns_test.go | 8 ++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/controller/replication/model/model.go b/src/controller/replication/model/model.go index dd4c1de71..495a048f7 100644 --- a/src/controller/replication/model/model.go +++ b/src/controller/replication/model/model.go @@ -17,14 +17,15 @@ package model import ( "encoding/json" "fmt" - "github.com/robfig/cron" "strings" "time" + "github.com/goharbor/harbor/src/lib" "github.com/goharbor/harbor/src/lib/errors" "github.com/goharbor/harbor/src/lib/log" "github.com/goharbor/harbor/src/pkg/reg/model" replicationmodel "github.com/goharbor/harbor/src/pkg/replication/model" + "github.com/robfig/cron" ) // Policy defines the structure of a replication policy @@ -112,6 +113,14 @@ func (p *Policy) Validate() error { } } + // valid the destination namespace + if len(p.DestNamespace) > 0 { + if !lib.RepositoryNameRe.MatchString(p.DestNamespace) { + return errors.New(nil).WithCode(errors.BadRequestCode). + WithMessage("invalid destination namespace: %s", p.DestNamespace) + } + } + // valid trigger if p.Trigger != nil { switch p.Trigger.Type { diff --git a/src/lib/patterns.go b/src/lib/patterns.go index cb813d8dd..0da79f5e3 100644 --- a/src/lib/patterns.go +++ b/src/lib/patterns.go @@ -26,8 +26,10 @@ var ( V2BlobURLRe = regexp.MustCompile(fmt.Sprintf(`^/v2/(?P<%s>%s)/blobs/(?P<%s>%s)$`, RepositorySubexp, reference.NameRegexp.String(), DigestSubexp, digest.DigestRegexp.String())) // V2BlobUploadURLRe is the regular expression for matching the request to v2 handler to upload a blob, the upload uuid currently is not put into a group V2BlobUploadURLRe = regexp.MustCompile(fmt.Sprintf(`^/v2/(?P<%s>%s)/blobs/uploads[/a-zA-Z0-9\-_\.=]*$`, RepositorySubexp, reference.NameRegexp.String())) - // V2CatalogURLRe is the regular expression for mathing the request to v2 handler to list catalog + // V2CatalogURLRe is the regular expression for matching the request to v2 handler to list catalog V2CatalogURLRe = regexp.MustCompile(`^/v2/_catalog(/.*)?$`) + // RepositoryNameRe is the regular expression for matching repository name + RepositoryNameRe = regexp.MustCompile(fmt.Sprintf("^%s$", reference.NameRegexp)) ) // MatchManifestURLPattern checks whether the provided path matches the manifest URL pattern, diff --git a/src/lib/patterns_test.go b/src/lib/patterns_test.go index cf5df129b..7d5ad7af8 100644 --- a/src/lib/patterns_test.go +++ b/src/lib/patterns_test.go @@ -102,3 +102,11 @@ func TestMatchCatalogURLPattern(t *testing.T) { assert.Equal(t, c.match, V2CatalogURLRe.MatchString(c.url), "failed for %s", c.url) } } + +func TestRepositoryNamePattern(t *testing.T) { + assert := assert.New(t) + assert.False(RepositoryNameRe.MatchString("a/*")) + assert.False(RepositoryNameRe.MatchString("a/")) + assert.True(RepositoryNameRe.MatchString("a/b")) + assert.True(RepositoryNameRe.MatchString("a")) +}