From a11fe2d19554ba52bfd0fa2f9ec4344824b3ffb7 Mon Sep 17 00:00:00 2001
From: Andrei Aaron Set debug=1 as a query parameter to export in legacy text format
+Profile Descriptions:
+
+
+Types of profiles available:
+
+
+full goroutine stack dump
+Count Profile
+`)
+
+ for _, profile := range profiles {
+ link := &url.URL{Path: profile.Href, RawQuery: "debug=1"}
+ fmt.Fprintf(&buff, " \n",
+ profile.Count, link, html.EscapeString(profile.Name))
+ }
+
+ buff.WriteString(`%d %s
+
+`)
+
+ for _, profile := range profiles {
+ fmt.Fprintf(&buff, "
+
\ No newline at end of file
diff --git a/pkg/debug/pprof/pprof_disabled.go b/pkg/debug/pprof/pprof_disabled.go
new file mode 100644
index 00000000..dfe98a55
--- /dev/null
+++ b/pkg/debug/pprof/pprof_disabled.go
@@ -0,0 +1,18 @@
+//go:build !profile
+// +build !profile
+
+package pprof
+
+import (
+ "github.com/gorilla/mux"
+
+ "zotregistry.io/zot/pkg/api/config"
+ "zotregistry.io/zot/pkg/log" //nolint:goimports
+)
+
+func SetupPprofRoutes(conf *config.Config, router *mux.Router, authFunc mux.MiddlewareFunc,
+ log log.Logger,
+) {
+ log.Warn().Msg("skipping enabling pprof extension because given zot binary " +
+ "doesn't include this feature, please build a binary that does so")
+}
diff --git a/pkg/debug/pprof/pprof_test.go b/pkg/debug/pprof/pprof_test.go
new file mode 100644
index 00000000..e08f343c
--- /dev/null
+++ b/pkg/debug/pprof/pprof_test.go
@@ -0,0 +1,189 @@
+//go:build profile
+// +build profile
+
+package pprof_test
+
+import (
+ "net/http"
+ "os"
+ "testing"
+
+ . "github.com/smartystreets/goconvey/convey"
+ "gopkg.in/resty.v1"
+
+ "zotregistry.io/zot/pkg/api"
+ "zotregistry.io/zot/pkg/api/config"
+ "zotregistry.io/zot/pkg/api/constants"
+ debugConstants "zotregistry.io/zot/pkg/debug/constants"
+ "zotregistry.io/zot/pkg/test"
+)
+
+func TestProfilingAuthz(t *testing.T) {
+ Convey("Make a new controller", t, func() {
+ port := test.GetFreePort()
+ baseURL := test.GetBaseURL(port)
+ adminUsername := "admin"
+ adminPassword := "admin"
+ username := "test"
+ password := "test"
+ authorizationAllRepos := "**"
+
+ testCreds := test.GetCredString(adminUsername, adminPassword) +
+ "\n" + test.GetCredString(username, password)
+ htpasswdPath := test.MakeHtpasswdFileFromString(testCreds)
+ defer os.Remove(htpasswdPath)
+
+ conf := config.New()
+ conf.HTTP.Port = port
+ conf.Storage.RootDirectory = t.TempDir()
+
+ Convey("Test with no access control", func() {
+ ctlr := api.NewController(conf)
+ cm := test.NewControllerManager(ctlr)
+ cm.StartAndWait(port)
+ defer cm.StopServer()
+
+ // unauthenticated clients should have access to /v2/
+ resp, err := resty.R().Get(baseURL + "/v2/")
+ So(err, ShouldBeNil)
+ So(resp, ShouldNotBeNil)
+ So(resp.StatusCode(), ShouldEqual, http.StatusOK)
+
+ // unauthenticated clients should have access to the profiling endpoints
+ resp, err = resty.R().Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "trace")
+ So(err, ShouldBeNil)
+ So(resp, ShouldNotBeNil)
+ So(resp.StatusCode(), ShouldEqual, http.StatusOK)
+
+ resp, err = resty.R().SetQueryParam("seconds", "1").
+ Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "profile")
+ So(err, ShouldBeNil)
+ So(resp, ShouldNotBeNil)
+ So(resp.StatusCode(), ShouldEqual, http.StatusOK)
+
+ resp, err = resty.R().Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "goroutine")
+ So(err, ShouldBeNil)
+ So(resp, ShouldNotBeNil)
+ So(resp.StatusCode(), ShouldEqual, http.StatusOK)
+
+ // test building the index
+ resp, err = resty.R().Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint)
+ So(err, ShouldBeNil)
+ So(resp, ShouldNotBeNil)
+ So(resp.StatusCode(), ShouldEqual, http.StatusOK)
+ })
+
+ Convey("Test with authenticated users and no anonymous policy", func() {
+ conf.HTTP.Auth = &config.AuthConfig{
+ HTPasswd: config.AuthHTPasswd{
+ Path: htpasswdPath,
+ },
+ }
+ conf.HTTP.AccessControl = &config.AccessControlConfig{
+ Repositories: config.Repositories{
+ authorizationAllRepos: config.PolicyGroup{
+ Policies: []config.Policy{
+ {
+ Users: []string{username},
+ Actions: []string{"read", "create"},
+ },
+ },
+ DefaultPolicy: []string{},
+ },
+ },
+ AdminPolicy: config.Policy{
+ Users: []string{adminUsername},
+ Actions: []string{},
+ },
+ }
+
+ ctlr := api.NewController(conf)
+ cm := test.NewControllerManager(ctlr)
+ cm.StartAndWait(port)
+ defer cm.StopServer()
+
+ // unauthenticated clients should not have access to /v2/
+ resp, err := resty.R().Get(baseURL + "/v2/")
+ So(err, ShouldBeNil)
+ So(resp, ShouldNotBeNil)
+ So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized)
+
+ // unauthenticated clients should not have access to the profiling endpoint
+ resp, err = resty.R().Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "trace")
+ So(err, ShouldBeNil)
+ So(resp, ShouldNotBeNil)
+ So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized)
+
+ // authenticated clients without permissions should not have access to the profiling endpoint
+ resp, err = resty.R().SetBasicAuth(username, password).
+ Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "trace")
+ So(err, ShouldBeNil)
+ So(resp, ShouldNotBeNil)
+ So(resp.StatusCode(), ShouldEqual, http.StatusForbidden)
+
+ // authenticated clients with admin permissions should have access to the profiling endpoint
+ resp, err = resty.R().SetBasicAuth(adminUsername, adminPassword).
+ Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "trace")
+ So(err, ShouldBeNil)
+ So(resp, ShouldNotBeNil)
+ So(resp.StatusCode(), ShouldEqual, http.StatusOK)
+ })
+
+ Convey("Test with authenticated users and anonymous policy", func() {
+ conf.HTTP.Auth = &config.AuthConfig{
+ HTPasswd: config.AuthHTPasswd{
+ Path: htpasswdPath,
+ },
+ }
+ conf.HTTP.AccessControl = &config.AccessControlConfig{
+ Repositories: config.Repositories{
+ authorizationAllRepos: config.PolicyGroup{
+ Policies: []config.Policy{
+ {
+ Users: []string{username},
+ Actions: []string{"read", "create"},
+ },
+ },
+ DefaultPolicy: []string{},
+ AnonymousPolicy: []string{"read"},
+ },
+ },
+ AdminPolicy: config.Policy{
+ Users: []string{adminUsername},
+ Actions: []string{},
+ },
+ }
+
+ ctlr := api.NewController(conf)
+ cm := test.NewControllerManager(ctlr)
+ cm.StartAndWait(port)
+ defer cm.StopServer()
+
+ // unauthenticated clients should have access to /v2/
+ resp, err := resty.R().Get(baseURL + "/v2/")
+ So(err, ShouldBeNil)
+ So(resp, ShouldNotBeNil)
+ So(resp.StatusCode(), ShouldEqual, http.StatusOK)
+
+ // unauthenticated clients should not have access to the profiling endpoint
+ resp, err = resty.R().Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "trace")
+ So(err, ShouldBeNil)
+ So(resp, ShouldNotBeNil)
+ So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized)
+
+ // authenticated clients without permissions should not have access to the profiling endpoint
+ resp, err = resty.R().SetBasicAuth(username, password).
+ Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "trace")
+ So(err, ShouldBeNil)
+ So(resp, ShouldNotBeNil)
+ So(resp.StatusCode(), ShouldEqual, http.StatusForbidden)
+
+ // authenticated clients with admin permissions should have access to the profiling endpoint
+ resp, err = resty.R().SetBasicAuth(adminUsername, adminPassword).
+ Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "trace")
+ So(err, ShouldBeNil)
+ So(resp, ShouldNotBeNil)
+ So(resp.StatusCode(), ShouldEqual, http.StatusOK)
+ })
+ })
+}
diff --git a/pkg/extensions/extension_image_trust_test.go b/pkg/extensions/extension_image_trust_test.go
index e04bcd1b..19a50dc9 100644
--- a/pkg/extensions/extension_image_trust_test.go
+++ b/pkg/extensions/extension_image_trust_test.go
@@ -728,6 +728,7 @@ func RunSignatureUploadAndVerificationTests(t *testing.T, cacheDriverParams map[
port := test.GetFreePort()
testCreds := test.GetCredString("admin", "admin") + "\n" + test.GetCredString("test", "test")
htpasswdPath := test.MakeHtpasswdFileFromString(testCreds)
+ defer os.Remove(htpasswdPath)
conf := config.New()
conf.HTTP.Port = port