mirror of
https://github.com/project-zot/zot.git
synced 2024-12-16 21:56:37 -05:00
be5ad66797
refactor(http): refactor http client to take options struct This commit updates the arguments for the `CreateHTTPClient` function to consume a struct which can be extended as required. It replaces the certPath argument with a struct of 3 paths for client ertificate, client key, and ca cert. It also adds a TLSEnabled option for when an HTTP Client is required without any further TLS config. Existing consumers of this function have been updated so that they can work as they do today. This change is a no-op for existing features. This allows for certificate paths to be customised and allows other modules to re-use the same HTTP client and get the benefits of mTLS support and per-host certificates. Signed-off-by: Vishwas Rajashekar <vrajashe@cisco.com>
179 lines
5.4 KiB
Go
179 lines
5.4 KiB
Go
package common_test
|
|
|
|
import (
|
|
"crypto/x509"
|
|
"net/http"
|
|
"os"
|
|
"path"
|
|
"testing"
|
|
|
|
. "github.com/smartystreets/goconvey/convey"
|
|
|
|
"zotregistry.dev/zot/pkg/common"
|
|
test "zotregistry.dev/zot/pkg/test/common"
|
|
)
|
|
|
|
func TestHTTPClient(t *testing.T) {
|
|
Convey("test getTLSConfig()", t, func() {
|
|
caCertPool, _ := x509.SystemCertPool()
|
|
tlsConfig, err := common.GetTLSConfig("wrongPath", caCertPool)
|
|
So(tlsConfig, ShouldBeNil)
|
|
So(err, ShouldNotBeNil)
|
|
|
|
tempDir := t.TempDir()
|
|
err = test.CopyTestKeysAndCerts(tempDir)
|
|
So(err, ShouldBeNil)
|
|
err = os.Chmod(path.Join(tempDir, "ca.crt"), 0o000)
|
|
So(err, ShouldBeNil)
|
|
_, err = common.GetTLSConfig(tempDir, caCertPool)
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
|
|
Convey("test CreateHTTPClient() no permissions on certificate", t, func() {
|
|
tempDir := t.TempDir()
|
|
err := test.CopyTestKeysAndCerts(tempDir)
|
|
So(err, ShouldBeNil)
|
|
err = os.Chmod(path.Join(tempDir, "ca.crt"), 0o000)
|
|
So(err, ShouldBeNil)
|
|
|
|
_, err = common.CreateHTTPClient(&common.HTTPClientOptions{
|
|
TLSEnabled: true,
|
|
VerifyTLS: true,
|
|
Host: "localhost",
|
|
CertOptions: common.HTTPClientCertOptions{
|
|
ClientCertFile: path.Join(tempDir, common.ClientCertFilename),
|
|
ClientKeyFile: path.Join(tempDir, common.ClientKeyFilename),
|
|
RootCaCertFile: path.Join(tempDir, common.CaCertFilename),
|
|
},
|
|
})
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
|
|
Convey("test CreateHTTPClient() no permissions on key", t, func() {
|
|
tempDir := t.TempDir()
|
|
err := test.CopyTestKeysAndCerts(tempDir)
|
|
So(err, ShouldBeNil)
|
|
err = os.Chmod(path.Join(tempDir, "client.key"), 0o000)
|
|
So(err, ShouldBeNil)
|
|
|
|
_, err = common.CreateHTTPClient(&common.HTTPClientOptions{
|
|
TLSEnabled: true,
|
|
VerifyTLS: true,
|
|
Host: "localhost",
|
|
CertOptions: common.HTTPClientCertOptions{
|
|
ClientCertFile: path.Join(tempDir, common.ClientCertFilename),
|
|
ClientKeyFile: path.Join(tempDir, common.ClientKeyFilename),
|
|
RootCaCertFile: path.Join(tempDir, common.CaCertFilename),
|
|
},
|
|
})
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
|
|
Convey("test CreateHTTPClient() no TLS", t, func() {
|
|
_, err := common.CreateHTTPClient(&common.HTTPClientOptions{})
|
|
So(err, ShouldBeNil)
|
|
})
|
|
|
|
Convey("test CreateHTTPClient() with only client cert configured", t, func() {
|
|
tempDir := t.TempDir()
|
|
err := test.CopyTestKeysAndCerts(tempDir)
|
|
So(err, ShouldBeNil)
|
|
|
|
_, err = common.CreateHTTPClient(&common.HTTPClientOptions{
|
|
TLSEnabled: true,
|
|
VerifyTLS: true,
|
|
Host: "localhost",
|
|
CertOptions: common.HTTPClientCertOptions{
|
|
ClientCertFile: path.Join(tempDir, common.ClientCertFilename),
|
|
},
|
|
})
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
|
|
Convey("test CreateHTTPClient() with only client key configured", t, func() {
|
|
tempDir := t.TempDir()
|
|
err := test.CopyTestKeysAndCerts(tempDir)
|
|
So(err, ShouldBeNil)
|
|
|
|
_, err = common.CreateHTTPClient(&common.HTTPClientOptions{
|
|
TLSEnabled: true,
|
|
VerifyTLS: true,
|
|
Host: "localhost",
|
|
CertOptions: common.HTTPClientCertOptions{
|
|
ClientKeyFile: path.Join(tempDir, common.ClientKeyFilename),
|
|
},
|
|
})
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
|
|
Convey("test CreateHTTPClient() with full certificate config", t, func() {
|
|
tempDir := t.TempDir()
|
|
err := test.CopyTestKeysAndCerts(tempDir)
|
|
So(err, ShouldBeNil)
|
|
|
|
client, err := common.CreateHTTPClient(&common.HTTPClientOptions{
|
|
TLSEnabled: true,
|
|
VerifyTLS: true,
|
|
Host: "localhost",
|
|
CertOptions: common.HTTPClientCertOptions{
|
|
ClientCertFile: path.Join(tempDir, common.ClientCertFilename),
|
|
ClientKeyFile: path.Join(tempDir, common.ClientKeyFilename),
|
|
RootCaCertFile: path.Join(tempDir, common.CaCertFilename),
|
|
},
|
|
})
|
|
So(err, ShouldBeNil)
|
|
|
|
htr, ok := client.Transport.(*http.Transport)
|
|
So(ok, ShouldBeTrue)
|
|
So(htr.TLSClientConfig.RootCAs, ShouldNotBeNil)
|
|
So(htr.TLSClientConfig.Certificates, ShouldNotBeEmpty)
|
|
})
|
|
|
|
Convey("test CreateHTTPClient() with no TLS verify", t, func() {
|
|
tempDir := t.TempDir()
|
|
err := test.CopyTestKeysAndCerts(tempDir)
|
|
So(err, ShouldBeNil)
|
|
|
|
client, err := common.CreateHTTPClient(&common.HTTPClientOptions{
|
|
TLSEnabled: true,
|
|
VerifyTLS: false,
|
|
Host: "localhost",
|
|
CertOptions: common.HTTPClientCertOptions{
|
|
ClientCertFile: path.Join(tempDir, common.ClientCertFilename),
|
|
ClientKeyFile: path.Join(tempDir, common.ClientKeyFilename),
|
|
RootCaCertFile: path.Join(tempDir, common.CaCertFilename),
|
|
},
|
|
})
|
|
So(err, ShouldBeNil)
|
|
|
|
htr, ok := client.Transport.(*http.Transport)
|
|
So(ok, ShouldBeTrue)
|
|
So(htr.TLSClientConfig.Certificates, ShouldBeEmpty)
|
|
So(htr.TLSClientConfig.RootCAs, ShouldBeNil)
|
|
So(htr.TLSClientConfig.InsecureSkipVerify, ShouldBeTrue)
|
|
})
|
|
|
|
Convey("test CreateHTTPClient() with no TLS, but TLS verify enabled", t, func() {
|
|
tempDir := t.TempDir()
|
|
err := test.CopyTestKeysAndCerts(tempDir)
|
|
So(err, ShouldBeNil)
|
|
|
|
client, err := common.CreateHTTPClient(&common.HTTPClientOptions{
|
|
TLSEnabled: false,
|
|
VerifyTLS: true,
|
|
Host: "localhost",
|
|
CertOptions: common.HTTPClientCertOptions{
|
|
ClientCertFile: path.Join(tempDir, common.ClientCertFilename),
|
|
ClientKeyFile: path.Join(tempDir, common.ClientKeyFilename),
|
|
RootCaCertFile: path.Join(tempDir, common.CaCertFilename),
|
|
},
|
|
})
|
|
So(err, ShouldBeNil)
|
|
|
|
htr, ok := client.Transport.(*http.Transport)
|
|
So(ok, ShouldBeTrue)
|
|
So(htr.TLSClientConfig.Certificates, ShouldBeEmpty)
|
|
So(htr.TLSClientConfig.RootCAs, ShouldBeNil)
|
|
So(htr.TLSClientConfig.InsecureSkipVerify, ShouldBeFalse)
|
|
})
|
|
}
|