mirror of https://github.com/portainer/portainer
102 lines
2.9 KiB
Go
102 lines
2.9 KiB
Go
package registries
|
|
|
|
import (
|
|
"bytes"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
)
|
|
|
|
// helper to build a multipart request for registry configure validation
|
|
func newConfigureRequest(t *testing.T, tls bool, skipVerify bool, includeCert bool, includeKey bool, includeCA bool) *http.Request {
|
|
t.Helper()
|
|
|
|
body := &bytes.Buffer{}
|
|
writer := multipart.NewWriter(body)
|
|
|
|
// flags
|
|
_ = writer.WriteField("TLS", map[bool]string{true: "true", false: "false"}[tls])
|
|
_ = writer.WriteField("TLSSkipVerify", map[bool]string{true: "true", false: "false"}[skipVerify])
|
|
|
|
// files
|
|
if includeCert {
|
|
fw, err := writer.CreateFormFile("TLSCertFile", "cert.pem")
|
|
if err != nil {
|
|
t.Fatalf("failed to create cert file: %v", err)
|
|
}
|
|
_, _ = fw.Write([]byte("CERTDATA"))
|
|
}
|
|
if includeKey {
|
|
fw, err := writer.CreateFormFile("TLSKeyFile", "key.pem")
|
|
if err != nil {
|
|
t.Fatalf("failed to create key file: %v", err)
|
|
}
|
|
_, _ = fw.Write([]byte("KEYDATA"))
|
|
}
|
|
if includeCA {
|
|
fw, err := writer.CreateFormFile("TLSCACertFile", "ca.pem")
|
|
if err != nil {
|
|
t.Fatalf("failed to create ca file: %v", err)
|
|
}
|
|
_, _ = fw.Write([]byte("CADATA"))
|
|
}
|
|
|
|
_ = writer.Close()
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/registries/1/configure", body)
|
|
req.Header.Set("Content-Type", writer.FormDataContentType())
|
|
return req
|
|
}
|
|
|
|
func Test_registryConfigurePayload_Validate_TLSBundleRules(t *testing.T) {
|
|
// passes when all three are uploaded
|
|
{
|
|
req := newConfigureRequest(t, true, false, true, true, true)
|
|
p := ®istryConfigurePayload{}
|
|
if err := p.Validate(req); err != nil {
|
|
t.Fatalf("expected validation to pass when all certs provided, got error: %v", err)
|
|
}
|
|
if len(p.TLSCertFile) == 0 || len(p.TLSKeyFile) == 0 || len(p.TLSCACertFile) == 0 {
|
|
t.Fatalf("expected payload to contain all cert bytes")
|
|
}
|
|
}
|
|
|
|
// passes when none are uploaded
|
|
{
|
|
req := newConfigureRequest(t, true, false, false, false, false)
|
|
p := ®istryConfigurePayload{}
|
|
if err := p.Validate(req); err != nil {
|
|
t.Fatalf("expected validation to pass when no certs provided, got error: %v", err)
|
|
}
|
|
if len(p.TLSCertFile) != 0 || len(p.TLSKeyFile) != 0 || len(p.TLSCACertFile) != 0 {
|
|
t.Fatalf("expected payload to have no cert bytes when none provided")
|
|
}
|
|
}
|
|
|
|
// fails on partial uploads (1 or 2 of the files)
|
|
partialCases := []struct {
|
|
name string
|
|
cert bool
|
|
key bool
|
|
ca bool
|
|
}{
|
|
{"only-cert", true, false, false},
|
|
{"only-key", false, true, false},
|
|
{"only-ca", false, false, true},
|
|
{"cert-and-key", true, true, false},
|
|
{"cert-and-ca", true, false, true},
|
|
{"key-and-ca", false, true, true},
|
|
}
|
|
|
|
for _, tc := range partialCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
req := newConfigureRequest(t, true, false, tc.cert, tc.key, tc.ca)
|
|
p := ®istryConfigurePayload{}
|
|
if err := p.Validate(req); err == nil {
|
|
t.Fatalf("expected validation to fail on partial cert upload")
|
|
}
|
|
})
|
|
}
|
|
}
|