mirror of
https://github.com/project-zot/zot.git
synced 2026-06-15 11:37:56 +08:00
2402296e9a
* fix: migrate to Go module v2 for proper semantic versioning This change updates the module path from 'zotregistry.dev/zot' to 'zotregistry.dev/zot/v2' to comply with Go's semantic versioning rules. According to Go's module versioning requirements, major version v2+ must include the major version in the module path. The current module path 'zotregistry.dev/zot' only supports v0.x.x and v1.x.x versions, making existing v2.x.x tags (like v2.1.8) unusable. Changes: - Updated go.mod module path to zotregistry.dev/zot/v2 - Updated all internal import paths across 280+ Go source files - Updated configuration files (golangcilint.yaml, gqlgen.yml) - Updated README.md Go reference badge This fix enables proper use of existing v2.x.x Git tags and allows external packages to import zot v2+ versions without compatibility errors. Resolves: Go module import compatibility for v2+ versions Fixes: #3071 Signed-off-by: Luca Muscariello <muscariello@ieee.org> * fix: regenerate GraphQL files with updated v2 import paths The gqlgen tool needs to regenerate the GraphQL schema files after the module path change to use the new v2 imports. Signed-off-by: Luca Muscariello <muscariello@ieee.org> --------- Signed-off-by: Luca Muscariello <muscariello@ieee.org>
197 lines
6.7 KiB
Go
197 lines
6.7 KiB
Go
//go:build profile
|
|
// +build profile
|
|
|
|
package pprof_test
|
|
|
|
import (
|
|
"net/http"
|
|
"os"
|
|
"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.GetCredString(adminUsername, adminPassword) +
|
|
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)
|
|
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)
|
|
})
|
|
})
|
|
}
|