zotregistry.io/zot@v1.4.4-0.20231124084042-02a8ed785457/pkg/debug/pprof/pprof_test.go (about) 1 //go:build profile 2 // +build profile 3 4 package pprof_test 5 6 import ( 7 "net/http" 8 "os" 9 "testing" 10 11 . "github.com/smartystreets/goconvey/convey" 12 "gopkg.in/resty.v1" 13 14 "zotregistry.io/zot/pkg/api" 15 "zotregistry.io/zot/pkg/api/config" 16 "zotregistry.io/zot/pkg/api/constants" 17 debugConstants "zotregistry.io/zot/pkg/debug/constants" 18 test "zotregistry.io/zot/pkg/test/common" 19 ) 20 21 func TestProfilingAuthz(t *testing.T) { 22 Convey("Make a new controller", t, func() { 23 port := test.GetFreePort() 24 baseURL := test.GetBaseURL(port) 25 adminUsername, seedAdminUser := test.GenerateRandomString() 26 adminPassword, seedAdminPass := test.GenerateRandomString() 27 username, seedUser := test.GenerateRandomString() 28 password, seedPass := test.GenerateRandomString() 29 authorizationAllRepos := test.AuthorizationAllRepos 30 31 testCreds := test.GetCredString(adminUsername, adminPassword) + 32 test.GetCredString(username, password) 33 htpasswdPath := test.MakeHtpasswdFileFromString(testCreds) 34 defer os.Remove(htpasswdPath) 35 36 conf := config.New() 37 conf.HTTP.Port = port 38 conf.Storage.RootDirectory = t.TempDir() 39 40 Convey("Test with no access control", func() { 41 ctlr := api.NewController(conf) 42 cm := test.NewControllerManager(ctlr) 43 cm.StartAndWait(port) 44 defer cm.StopServer() 45 46 // unauthenticated clients should have access to /v2/ 47 resp, err := resty.R().Get(baseURL + "/v2/") 48 So(err, ShouldBeNil) 49 So(resp, ShouldNotBeNil) 50 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 51 52 // unauthenticated clients should have access to the profiling endpoints 53 resp, err = resty.R().Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "trace") 54 So(err, ShouldBeNil) 55 So(resp, ShouldNotBeNil) 56 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 57 58 resp, err = resty.R().SetQueryParam("seconds", "1"). 59 Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "profile") 60 So(err, ShouldBeNil) 61 So(resp, ShouldNotBeNil) 62 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 63 64 resp, err = resty.R().Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "goroutine") 65 So(err, ShouldBeNil) 66 So(resp, ShouldNotBeNil) 67 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 68 69 // test building the index 70 resp, err = resty.R().Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint) 71 So(err, ShouldBeNil) 72 So(resp, ShouldNotBeNil) 73 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 74 }) 75 76 Convey("Test with authenticated users and no anonymous policy", func() { 77 conf.HTTP.Auth = &config.AuthConfig{ 78 HTPasswd: config.AuthHTPasswd{ 79 Path: htpasswdPath, 80 }, 81 } 82 conf.HTTP.AccessControl = &config.AccessControlConfig{ 83 Repositories: config.Repositories{ 84 authorizationAllRepos: config.PolicyGroup{ 85 Policies: []config.Policy{ 86 { 87 Users: []string{username}, 88 Actions: []string{"read", "create"}, 89 }, 90 }, 91 DefaultPolicy: []string{}, 92 }, 93 }, 94 AdminPolicy: config.Policy{ 95 Users: []string{adminUsername}, 96 Actions: []string{}, 97 }, 98 } 99 100 ctlr := api.NewController(conf) 101 ctlr.Log.Info().Int64("seedAdminUser", seedAdminUser).Int64("seedAdminPass", seedAdminPass). 102 Msg("random seed for admin username & password") 103 ctlr.Log.Info().Int64("seedUser", seedUser).Int64("seedPass", seedPass).Msg("random seed for username & password") 104 cm := test.NewControllerManager(ctlr) 105 cm.StartAndWait(port) 106 defer cm.StopServer() 107 108 // unauthenticated clients should not have access to /v2/ 109 resp, err := resty.R().Get(baseURL + "/v2/") 110 So(err, ShouldBeNil) 111 So(resp, ShouldNotBeNil) 112 So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) 113 114 // unauthenticated clients should not have access to the profiling endpoint 115 resp, err = resty.R().Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "trace") 116 So(err, ShouldBeNil) 117 So(resp, ShouldNotBeNil) 118 So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) 119 120 // authenticated clients without permissions should not have access to the profiling endpoint 121 resp, err = resty.R().SetBasicAuth(username, password). 122 Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "trace") 123 So(err, ShouldBeNil) 124 So(resp, ShouldNotBeNil) 125 So(resp.StatusCode(), ShouldEqual, http.StatusForbidden) 126 127 // authenticated clients with admin permissions should have access to the profiling endpoint 128 resp, err = resty.R().SetBasicAuth(adminUsername, adminPassword). 129 Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "trace") 130 So(err, ShouldBeNil) 131 So(resp, ShouldNotBeNil) 132 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 133 }) 134 135 Convey("Test with authenticated users and anonymous policy", func() { 136 conf.HTTP.Auth = &config.AuthConfig{ 137 HTPasswd: config.AuthHTPasswd{ 138 Path: htpasswdPath, 139 }, 140 } 141 conf.HTTP.AccessControl = &config.AccessControlConfig{ 142 Repositories: config.Repositories{ 143 authorizationAllRepos: config.PolicyGroup{ 144 Policies: []config.Policy{ 145 { 146 Users: []string{username}, 147 Actions: []string{"read", "create"}, 148 }, 149 }, 150 DefaultPolicy: []string{}, 151 AnonymousPolicy: []string{"read"}, 152 }, 153 }, 154 AdminPolicy: config.Policy{ 155 Users: []string{adminUsername}, 156 Actions: []string{}, 157 }, 158 } 159 160 ctlr := api.NewController(conf) 161 cm := test.NewControllerManager(ctlr) 162 cm.StartAndWait(port) 163 defer cm.StopServer() 164 165 // unauthenticated clients should have access to /v2/ 166 resp, err := resty.R().Get(baseURL + "/v2/") 167 So(err, ShouldBeNil) 168 So(resp, ShouldNotBeNil) 169 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 170 171 // unauthenticated clients should not have access to the profiling endpoint 172 resp, err = resty.R().Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "trace") 173 So(err, ShouldBeNil) 174 So(resp, ShouldNotBeNil) 175 So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) 176 177 // authenticated clients without permissions should not have access to the profiling endpoint 178 resp, err = resty.R().SetBasicAuth(username, password). 179 Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "trace") 180 So(err, ShouldBeNil) 181 So(resp, ShouldNotBeNil) 182 So(resp.StatusCode(), ShouldEqual, http.StatusForbidden) 183 184 // authenticated clients with admin permissions should have access to the profiling endpoint 185 resp, err = resty.R().SetBasicAuth(adminUsername, adminPassword). 186 Get(baseURL + constants.RoutePrefix + debugConstants.ProfilingEndpoint + "trace") 187 So(err, ShouldBeNil) 188 So(resp, ShouldNotBeNil) 189 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 190 }) 191 }) 192 }