Files
Andrei Aaron 9dfa7c3ae6 refactor(test): new apis for creating temporary files (#3605)
Replace MakeTempFile usage with MakeTempFilePath and MakeTempFileWithContent
helpers that automatically handle file lifecycle. This prevents resource
leaks by ensuring temporary files are properly closed.

Shoudld also make the tests easier to read.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-12-05 09:54:38 +02:00

193 lines
6.6 KiB
Go

//go:build profile
package pprof_test
import (
"net/http"
"testing"
. "github.com/smartystreets/goconvey/convey"
"gopkg.in/resty.v1"
"zotregistry.dev/zot/v2/pkg/api"
"zotregistry.dev/zot/v2/pkg/api/config"
"zotregistry.dev/zot/v2/pkg/api/constants"
debugConstants "zotregistry.dev/zot/v2/pkg/debug/constants"
test "zotregistry.dev/zot/v2/pkg/test/common"
)
func TestProfilingAuthz(t *testing.T) {
Convey("Make a new controller", t, func() {
port := test.GetFreePort()
baseURL := test.GetBaseURL(port)
adminUsername, seedAdminUser := test.GenerateRandomString()
adminPassword, seedAdminPass := test.GenerateRandomString()
username, seedUser := test.GenerateRandomString()
password, seedPass := test.GenerateRandomString()
authorizationAllRepos := test.AuthorizationAllRepos
testCreds := test.GetBcryptCredString(adminUsername, adminPassword) +
test.GetBcryptCredString(username, password)
htpasswdPath := test.MakeHtpasswdFileFromString(t, testCreds)
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)
ctlr.Log.Info().Int64("seedAdminUser", seedAdminUser).Int64("seedAdminPass", seedAdminPass).
Msg("random seed for admin username & password")
ctlr.Log.Info().Int64("seedUser", seedUser).Int64("seedPass", seedPass).Msg("random seed for username & password")
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)
})
})
}