mirror of
https://github.com/project-zot/zot.git
synced 2026-06-18 21:48:04 +08:00
9dfa7c3ae6
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>
263 lines
7.5 KiB
Go
263 lines
7.5 KiB
Go
//go:build search
|
|
|
|
package client_test
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"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"
|
|
"zotregistry.dev/zot/v2/pkg/cli/client"
|
|
extConf "zotregistry.dev/zot/v2/pkg/extensions/config"
|
|
test "zotregistry.dev/zot/v2/pkg/test/common"
|
|
)
|
|
|
|
const (
|
|
BaseSecureURL1 = "https://127.0.0.1:8088"
|
|
HOST1 = "127.0.0.1:8088"
|
|
SecurePort1 = "8088"
|
|
BaseSecureURL2 = "https://127.0.0.1:8089"
|
|
SecurePort2 = "8089"
|
|
BaseSecureURL3 = "https://127.0.0.1:8090"
|
|
SecurePort3 = "8090"
|
|
ServerCert = "../../../test/data/server.cert"
|
|
ServerKey = "../../../test/data/server.key"
|
|
CACert = "../../../test/data/ca.crt"
|
|
sourceCertsDir = "../../../test/data"
|
|
certsDir1 = ".config/containers/certs.d/127.0.0.1:8088"
|
|
)
|
|
|
|
func TestTLSWithAuth(t *testing.T) {
|
|
Convey("Make a new controller", t, func() {
|
|
caCert, err := os.ReadFile(CACert)
|
|
So(err, ShouldBeNil)
|
|
caCertPool := x509.NewCertPool()
|
|
caCertPool.AppendCertsFromPEM(caCert)
|
|
|
|
resty.SetTLSClientConfig(&tls.Config{RootCAs: caCertPool, MinVersion: tls.VersionTLS12})
|
|
|
|
defer func() { resty.SetTLSClientConfig(nil) }()
|
|
|
|
conf := config.New()
|
|
conf.HTTP.Port = SecurePort1
|
|
username, seedUser := test.GenerateRandomString()
|
|
password, seedPass := test.GenerateRandomString()
|
|
|
|
htpasswdPath := test.MakeHtpasswdFileFromString(t, test.GetBcryptCredString(username, password))
|
|
|
|
conf.HTTP.Auth = &config.AuthConfig{
|
|
HTPasswd: config.AuthHTPasswd{
|
|
Path: htpasswdPath,
|
|
},
|
|
}
|
|
|
|
conf.HTTP.TLS = &config.TLSConfig{
|
|
Cert: ServerCert,
|
|
Key: ServerKey,
|
|
CACert: CACert,
|
|
}
|
|
|
|
enable := true
|
|
conf.Extensions = &extConf.ExtensionConfig{
|
|
Search: &extConf.SearchConfig{BaseConfig: extConf.BaseConfig{Enable: &enable}},
|
|
}
|
|
|
|
ctlr := api.NewController(conf)
|
|
ctlr.Log.Info().Int64("seedUser", seedUser).Int64("seedPass", seedPass).Msg("random seed for username & password")
|
|
ctlr.Config.Storage.RootDirectory = t.TempDir()
|
|
|
|
cm := test.NewControllerManager(ctlr)
|
|
cm.StartAndWait(conf.HTTP.Port)
|
|
defer cm.StopServer()
|
|
|
|
Convey("Test with htpassw auth", func() {
|
|
_ = makeConfigFile(t, `{"configs":[{"_name":"imagetest","showspinner":false}]}`)
|
|
|
|
// Use the HOME that makeConfigFile set (temp directory) for certificates
|
|
home := os.Getenv("HOME")
|
|
destCertsDir := filepath.Join(home, certsDir1)
|
|
err := test.CopyTestKeysAndCerts(destCertsDir)
|
|
So(err, ShouldBeNil)
|
|
|
|
defer os.RemoveAll(destCertsDir)
|
|
|
|
args := []string{"name", "dummyImageName", "--url", HOST1}
|
|
imageCmd := client.NewImageCommand(client.NewSearchService())
|
|
imageBuff := bytes.NewBufferString("")
|
|
imageCmd.SetOut(imageBuff)
|
|
imageCmd.SetErr(imageBuff)
|
|
imageCmd.SetArgs(args)
|
|
err = imageCmd.Execute()
|
|
So(err, ShouldNotBeNil)
|
|
So(imageBuff.String(), ShouldContainSubstring, "scheme not provided")
|
|
|
|
args = []string{"list", "--config", "imagetest"}
|
|
|
|
_ = makeConfigFile(t,
|
|
fmt.Sprintf(`{"configs":[{"_name":"imagetest","url":"%s%s%s","showspinner":false}]}`,
|
|
BaseSecureURL1, constants.RoutePrefix, constants.ExtCatalogPrefix))
|
|
|
|
// Ensure certificates are in the HOME directory that makeConfigFile set
|
|
home = os.Getenv("HOME")
|
|
destCertsDir = filepath.Join(home, certsDir1)
|
|
err = test.CopyTestKeysAndCerts(destCertsDir)
|
|
So(err, ShouldBeNil)
|
|
|
|
imageCmd = client.NewImageCommand(client.NewSearchService())
|
|
imageBuff = bytes.NewBufferString("")
|
|
imageCmd.SetOut(imageBuff)
|
|
imageCmd.SetErr(imageBuff)
|
|
imageCmd.SetArgs(args)
|
|
err = imageCmd.Execute()
|
|
So(err, ShouldNotBeNil)
|
|
So(imageBuff.String(), ShouldContainSubstring, "check credentials")
|
|
|
|
user := fmt.Sprintf("%s:%s", username, password)
|
|
args = []string{"-u", user, "--config", "imagetest"}
|
|
|
|
_ = makeConfigFile(t,
|
|
fmt.Sprintf(`{"configs":[{"_name":"imagetest","url":"%s%s%s","showspinner":false}]}`,
|
|
BaseSecureURL1, constants.RoutePrefix, constants.ExtCatalogPrefix))
|
|
|
|
imageCmd = client.NewImageCommand(client.NewSearchService())
|
|
imageBuff = bytes.NewBufferString("")
|
|
imageCmd.SetOut(imageBuff)
|
|
imageCmd.SetErr(imageBuff)
|
|
imageCmd.SetArgs(args)
|
|
err = imageCmd.Execute()
|
|
So(err, ShouldBeNil)
|
|
})
|
|
})
|
|
}
|
|
|
|
func TestTLSWithoutAuth(t *testing.T) {
|
|
Convey("Home certs - Make a new controller", t, func() {
|
|
caCert, err := os.ReadFile(CACert)
|
|
So(err, ShouldBeNil)
|
|
caCertPool := x509.NewCertPool()
|
|
caCertPool.AppendCertsFromPEM(caCert)
|
|
|
|
resty.SetTLSClientConfig(&tls.Config{RootCAs: caCertPool, MinVersion: tls.VersionTLS12})
|
|
|
|
defer func() { resty.SetTLSClientConfig(nil) }()
|
|
|
|
conf := config.New()
|
|
conf.HTTP.Port = SecurePort1
|
|
conf.HTTP.TLS = &config.TLSConfig{
|
|
Cert: ServerCert,
|
|
Key: ServerKey,
|
|
CACert: CACert,
|
|
}
|
|
|
|
enable := true
|
|
conf.Extensions = &extConf.ExtensionConfig{
|
|
Search: &extConf.SearchConfig{BaseConfig: extConf.BaseConfig{Enable: &enable}},
|
|
}
|
|
|
|
ctlr := api.NewController(conf)
|
|
ctlr.Config.Storage.RootDirectory = t.TempDir()
|
|
|
|
cm := test.NewControllerManager(ctlr)
|
|
cm.StartAndWait(conf.HTTP.Port)
|
|
defer cm.StopServer()
|
|
|
|
Convey("Certs in user's home", func() {
|
|
_ = makeConfigFile(t,
|
|
fmt.Sprintf(`{"configs":[{"_name":"imagetest","url":"%s%s%s","showspinner":false}]}`,
|
|
BaseSecureURL1, constants.RoutePrefix, constants.ExtCatalogPrefix))
|
|
|
|
home := os.Getenv("HOME")
|
|
destCertsDir := filepath.Join(home, certsDir1)
|
|
|
|
err := test.CopyFiles(sourceCertsDir, destCertsDir)
|
|
So(err, ShouldBeNil)
|
|
|
|
defer os.RemoveAll(destCertsDir)
|
|
|
|
args := []string{"list", "--config", "imagetest"}
|
|
imageCmd := client.NewImageCommand(client.NewSearchService())
|
|
imageBuff := bytes.NewBufferString("")
|
|
imageCmd.SetOut(imageBuff)
|
|
imageCmd.SetErr(imageBuff)
|
|
imageCmd.SetArgs(args)
|
|
err = imageCmd.Execute()
|
|
So(err, ShouldBeNil)
|
|
})
|
|
})
|
|
}
|
|
|
|
func TestTLSBadCerts(t *testing.T) {
|
|
Convey("Make a new controller", t, func() {
|
|
caCert, err := os.ReadFile(CACert)
|
|
So(err, ShouldBeNil)
|
|
|
|
caCertPool := x509.NewCertPool()
|
|
caCertPool.AppendCertsFromPEM(caCert)
|
|
|
|
resty.SetTLSClientConfig(&tls.Config{RootCAs: caCertPool, MinVersion: tls.VersionTLS12})
|
|
|
|
defer func() { resty.SetTLSClientConfig(nil) }()
|
|
|
|
conf := config.New()
|
|
conf.HTTP.Port = SecurePort3
|
|
conf.HTTP.TLS = &config.TLSConfig{
|
|
Cert: ServerCert,
|
|
Key: ServerKey,
|
|
CACert: CACert,
|
|
}
|
|
|
|
ctlr := api.NewController(conf)
|
|
ctlr.Config.Storage.RootDirectory = t.TempDir()
|
|
|
|
cm := test.NewControllerManager(ctlr)
|
|
cm.StartAndWait(conf.HTTP.Port)
|
|
defer cm.StopServer()
|
|
|
|
Convey("Test with system certs", func() {
|
|
_ = makeConfigFile(t,
|
|
fmt.Sprintf(`{"configs":[{"_name":"imagetest","url":"%s%s%s","showspinner":false}]}`,
|
|
BaseSecureURL3, constants.RoutePrefix, constants.ExtCatalogPrefix))
|
|
|
|
args := []string{"list", "--config", "imagetest"}
|
|
imageCmd := client.NewImageCommand(client.NewSearchService())
|
|
imageBuff := bytes.NewBufferString("")
|
|
imageCmd.SetOut(imageBuff)
|
|
imageCmd.SetErr(imageBuff)
|
|
imageCmd.SetArgs(args)
|
|
err := imageCmd.Execute()
|
|
So(err, ShouldNotBeNil)
|
|
So(imageBuff.String(), ShouldContainSubstring, "certificate signed by unknown authority")
|
|
})
|
|
})
|
|
}
|
|
|
|
func makeConfigFile(t *testing.T, content string) string {
|
|
t.Helper()
|
|
tempDir := t.TempDir()
|
|
os.Setenv("HOME", tempDir)
|
|
|
|
home, err := os.UserHomeDir()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
configPath := path.Join(home, "/.zot")
|
|
|
|
if err := os.WriteFile(configPath, []byte(content), 0o600); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return configPath
|
|
}
|