From 9c3fc28250b9d7d3956b7395367016ab9c6a79e3 Mon Sep 17 00:00:00 2001 From: "stonezdj(Daojun Zhang)" Date: Fri, 19 Apr 2024 10:14:28 +0800 Subject: [PATCH] Allow generate sbom in proxy cache project (#20298) Signed-off-by: stonezdj --- src/server/middleware/repoproxy/proxy.go | 14 +++++++--- src/server/middleware/repoproxy/proxy_test.go | 28 +++++++++++++++++-- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/server/middleware/repoproxy/proxy.go b/src/server/middleware/repoproxy/proxy.go index 5fb44a681..ddb201784 100644 --- a/src/server/middleware/repoproxy/proxy.go +++ b/src/server/middleware/repoproxy/proxy.go @@ -28,6 +28,7 @@ import ( "github.com/goharbor/harbor/src/controller/proxy" "github.com/goharbor/harbor/src/controller/registry" "github.com/goharbor/harbor/src/lib" + "github.com/goharbor/harbor/src/lib/config" "github.com/goharbor/harbor/src/lib/errors" httpLib "github.com/goharbor/harbor/src/lib/http" "github.com/goharbor/harbor/src/lib/log" @@ -259,16 +260,21 @@ func setHeaders(w http.ResponseWriter, size int64, mediaType string, dig string) } // isProxySession check if current security context is proxy session -func isProxySession(ctx context.Context) bool { +func isProxySession(ctx context.Context, projectName string) bool { sc, ok := security.FromContext(ctx) if !ok { log.Error("Failed to get security context") return false } - if sc.GetUsername() == proxycachesecret.ProxyCacheService { + username := sc.GetUsername() + if username == proxycachesecret.ProxyCacheService { return true } - return false + // it should include the auto generate SBOM session, so that it could generate SBOM accessory in proxy cache project + robotPrefix := config.RobotPrefix(ctx) + scannerPrefix := config.ScannerRobotPrefix(ctx) + prefix := fmt.Sprintf("%s%s+%s", robotPrefix, projectName, scannerPrefix) + return strings.HasPrefix(username, prefix) } // DisableBlobAndManifestUploadMiddleware disable push artifact to a proxy project with a non-proxy session @@ -281,7 +287,7 @@ func DisableBlobAndManifestUploadMiddleware() func(http.Handler) http.Handler { httpLib.SendError(w, err) return } - if p.IsProxy() && !isProxySession(ctx) { + if p.IsProxy() && !isProxySession(ctx, art.ProjectName) { httpLib.SendError(w, errors.DeniedError( errors.Errorf("can not push artifact to a proxy project: %v", p.Name))) diff --git a/src/server/middleware/repoproxy/proxy_test.go b/src/server/middleware/repoproxy/proxy_test.go index 4b7ee3d75..c47f20db0 100644 --- a/src/server/middleware/repoproxy/proxy_test.go +++ b/src/server/middleware/repoproxy/proxy_test.go @@ -18,7 +18,9 @@ import ( "context" "testing" + "github.com/goharbor/harbor/src/common/models" "github.com/goharbor/harbor/src/common/security" + "github.com/goharbor/harbor/src/common/security/local" "github.com/goharbor/harbor/src/common/security/proxycachesecret" securitySecret "github.com/goharbor/harbor/src/common/security/secret" ) @@ -29,6 +31,19 @@ func TestIsProxySession(t *testing.T) { sc2 := proxycachesecret.NewSecurityContext("library/hello-world") proxyCtx := security.NewContext(context.Background(), sc2) + + user := &models.User{ + Username: "robot$library+scanner-8ec3b47a-fd29-11ee-9681-0242c0a87009", + } + userSc := local.NewSecurityContext(user) + scannerCtx := security.NewContext(context.Background(), userSc) + + otherRobot := &models.User{ + Username: "robot$library+test-8ec3b47a-fd29-11ee-9681-0242c0a87009", + } + userSc2 := local.NewSecurityContext(otherRobot) + nonScannerCtx := security.NewContext(context.Background(), userSc2) + cases := []struct { name string in context.Context @@ -44,15 +59,24 @@ func TestIsProxySession(t *testing.T) { in: proxyCtx, want: true, }, + { + name: `robot account`, + in: scannerCtx, + want: true, + }, + { + name: `non scanner robot`, + in: nonScannerCtx, + want: false, + }, } for _, tt := range cases { t.Run(tt.name, func(t *testing.T) { - got := isProxySession(tt.in) + got := isProxySession(tt.in, "library") if got != tt.want { t.Errorf(`(%v) = %v; want "%v"`, tt.in, got, tt.want) } - }) } }