mirror of
https://github.com/grafana/grafana.git
synced 2024-12-02 05:29:42 -06:00
b765c21d4c
* Plugins: Pass PDC file contents in requests * go mod tidy * undo go.mod changes * fix linter * fix tests * undo unnecessary changes * update dep * join with comma * update naming * bump SDK
231 lines
5.5 KiB
Go
231 lines
5.5 KiB
Go
package setting
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"encoding/pem"
|
|
"errors"
|
|
"fmt"
|
|
"math/big"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gopkg.in/ini.v1"
|
|
)
|
|
|
|
func TestReadSecureSocksDSProxySettings(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tempDir := t.TempDir()
|
|
testFilePath := filepath.Join(tempDir, "test")
|
|
testFileData := "foobar"
|
|
err := os.WriteFile(testFilePath, []byte(testFileData), 0600)
|
|
require.NoError(t, err)
|
|
|
|
rootCACertFilePath := filepath.Join(tempDir, "ca.cert")
|
|
// nolint:gosec
|
|
caCertFile, err := os.Create(rootCACertFilePath)
|
|
require.NoError(t, err)
|
|
defer func() {
|
|
err = caCertFile.Close()
|
|
require.NoError(t, err)
|
|
}()
|
|
|
|
rootCaFileData := createTestRootCAFile(t, rootCACertFilePath)
|
|
require.NoError(t, err)
|
|
|
|
cases := []struct {
|
|
description string
|
|
iniFile *ini.File
|
|
expectedSettings SecureSocksDSProxySettings
|
|
expectedErr error
|
|
}{
|
|
{
|
|
description: "default values",
|
|
iniFile: mustNewIniFile(`
|
|
[secure_socks_datasource_proxy]
|
|
`),
|
|
expectedSettings: SecureSocksDSProxySettings{
|
|
Enabled: false,
|
|
ShowUI: true,
|
|
AllowInsecure: false,
|
|
ClientCertFilePath: "",
|
|
ClientCert: "",
|
|
ClientKey: "",
|
|
ClientKeyFilePath: "",
|
|
RootCAs: []string{},
|
|
RootCAFilePaths: []string{},
|
|
ProxyAddress: "",
|
|
ServerName: "",
|
|
},
|
|
},
|
|
{
|
|
description: "one or more root ca is required",
|
|
iniFile: mustNewIniFile(`
|
|
[secure_socks_datasource_proxy]
|
|
enabled = true
|
|
proxy_address = address
|
|
`),
|
|
expectedErr: errors.New("one or more rootCA required"),
|
|
},
|
|
{
|
|
description: "client cert is required",
|
|
iniFile: mustNewIniFile(`
|
|
[secure_socks_datasource_proxy]
|
|
enabled = true
|
|
proxy_address = address
|
|
root_ca_cert = cert
|
|
`),
|
|
expectedErr: errors.New("client key pair required"),
|
|
},
|
|
{
|
|
description: "client key is required",
|
|
iniFile: mustNewIniFile(`
|
|
[secure_socks_datasource_proxy]
|
|
enabled = true
|
|
proxy_address = address
|
|
root_ca_cert = cert1
|
|
client_cert = cert2
|
|
`),
|
|
expectedErr: errors.New("client key pair required"),
|
|
},
|
|
{
|
|
description: "server name is required",
|
|
iniFile: mustNewIniFile(`
|
|
[secure_socks_datasource_proxy]
|
|
enabled = true
|
|
proxy_address = address
|
|
root_ca_cert = cert1
|
|
client_cert = cert2
|
|
client_key = key
|
|
`),
|
|
expectedErr: errors.New("server name required"),
|
|
},
|
|
{
|
|
description: "proxy address is required",
|
|
iniFile: mustNewIniFile(`
|
|
[secure_socks_datasource_proxy]
|
|
enabled = true
|
|
root_ca_cert = cert1
|
|
client_cert = cert2
|
|
client_key = key
|
|
server_name = name
|
|
`),
|
|
expectedErr: errors.New("proxy address required"),
|
|
},
|
|
{
|
|
description: "root ca, client cert and client key are not required in insecure more",
|
|
iniFile: mustNewIniFile(`
|
|
[secure_socks_datasource_proxy]
|
|
enabled = true
|
|
proxy_address = address
|
|
server_name = name
|
|
allow_insecure = true
|
|
`),
|
|
expectedSettings: SecureSocksDSProxySettings{
|
|
Enabled: true,
|
|
ProxyAddress: "address",
|
|
ServerName: "name",
|
|
ShowUI: true,
|
|
AllowInsecure: true,
|
|
RootCAFilePaths: []string{},
|
|
RootCAs: []string{},
|
|
},
|
|
},
|
|
{
|
|
description: "custom values",
|
|
iniFile: mustNewIniFile(fmt.Sprintf(`
|
|
[secure_socks_datasource_proxy]
|
|
enabled = true
|
|
client_cert = %s
|
|
client_key = %s
|
|
root_ca_cert = %s
|
|
proxy_address = proxy_address
|
|
server_name = server_name
|
|
show_ui = false
|
|
allow_insecure = false
|
|
`, testFilePath, testFilePath, rootCACertFilePath)),
|
|
expectedSettings: SecureSocksDSProxySettings{
|
|
Enabled: true,
|
|
ShowUI: false,
|
|
AllowInsecure: false,
|
|
ClientCert: testFileData,
|
|
ClientCertFilePath: testFilePath,
|
|
ClientKey: testFileData,
|
|
ClientKeyFilePath: testFilePath,
|
|
RootCAs: []string{rootCaFileData},
|
|
RootCAFilePaths: []string{rootCACertFilePath},
|
|
ProxyAddress: "proxy_address",
|
|
ServerName: "server_name",
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range cases {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
settings, err := readSecureSocksDSProxySettings(tt.iniFile)
|
|
|
|
if tt.expectedErr != nil {
|
|
assert.Equal(t, tt.expectedErr, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, tt.expectedSettings, settings)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func createTestRootCAFile(t *testing.T, path string) string {
|
|
t.Helper()
|
|
|
|
ca := &x509.Certificate{
|
|
SerialNumber: big.NewInt(2019),
|
|
Subject: pkix.Name{
|
|
Organization: []string{"Grafana Labs"},
|
|
CommonName: "Grafana",
|
|
},
|
|
NotBefore: time.Now(),
|
|
NotAfter: time.Now().AddDate(10, 0, 0),
|
|
IsCA: true,
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
|
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
|
BasicConstraintsValid: true,
|
|
}
|
|
caPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
|
|
require.NoError(t, err)
|
|
caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey)
|
|
require.NoError(t, err)
|
|
|
|
// nolint:gosec
|
|
caCertFile, err := os.Create(path)
|
|
require.NoError(t, err)
|
|
|
|
block := &pem.Block{
|
|
Type: "CERTIFICATE",
|
|
Bytes: caBytes,
|
|
}
|
|
err = pem.Encode(caCertFile, block)
|
|
require.NoError(t, err)
|
|
|
|
buf := new(bytes.Buffer)
|
|
err = pem.Encode(buf, block)
|
|
require.NoError(t, err)
|
|
|
|
return buf.String()
|
|
}
|
|
|
|
func mustNewIniFile(fileContents string) *ini.File {
|
|
file, err := ini.Load([]byte(fileContents))
|
|
if err != nil {
|
|
panic(fmt.Sprintf("creating ini file for test: %s", err))
|
|
}
|
|
return file
|
|
}
|