fleet/server/utils_test.go
Roberto Dip 319b64f368
allow to set mdm.windows_settings.custom_settings in configs (#15145)
for #14361 this adds the bits related to saving a slice of strings with
paths to configuration profiles.

---------

Co-authored-by: Martin Angers <martin.n.angers@gmail.com>
Co-authored-by: Marko Lisica <83164494+marko-lisica@users.noreply.github.com>
2023-11-15 13:58:46 -03:00

178 lines
5.4 KiB
Go

package server
import (
"encoding/base64"
"errors"
"net/url"
"testing"
"github.com/stretchr/testify/require"
)
func TestMaskSecretURLParams(t *testing.T) {
secretKeywords := []string{"secret", "token", "key", "password"}
mask := "MASKED"
type testCase struct {
name string
rawURL string
expected string
}
cases := []testCase{
{
name: "no params",
rawURL: "https://example.com",
expected: "https://example.com",
},
{
name: "user info redacted",
rawURL: "https://user:P@$$w0rD@example.com/foo/bar?baz=qux&secret_key=baz",
expected: "https://user:xxxxx@example.com/foo/bar?baz=qux&secret_key=" + mask,
},
}
for i, kw := range secretKeywords {
cases = append(cases, testCase{
name: "single " + kw,
rawURL: "https://example.com?" + kw + "=foo",
expected: "https://example.com?" + kw + "=" + mask,
})
cases = append(cases, testCase{
name: "multiple " + kw,
rawURL: "https://example.com?" + kw + "=foo" + "&bar_" + kw + "=bar",
expected: "https://example.com?" + kw + "=" + mask + "&bar_" + kw + "=" + mask,
})
cases = append(cases, testCase{
name: "multiple " + kw + " with other params",
rawURL: "https://example.com?foo=bar&" + kw + "=foo" + "&bar_" + kw + "=bar",
expected: "https://example.com?foo=bar&" + kw + "=" + mask + "&bar_" + kw + "=" + mask,
})
cases = append(cases, testCase{
name: "multiple " + kw + " with other params and fragment",
rawURL: "https://example.com?foo=bar&" + kw + "=foo" + "&bar_" + kw + "=bar#fragment",
expected: "https://example.com?foo=bar&" + kw + "=" + mask + "&bar_" + kw + "=" + mask + "#fragment",
})
kw2 := secretKeywords[(i+1)%len(secretKeywords)]
cases = append(cases, testCase{
name: "combined " + kw + " and " + kw2,
rawURL: "https://example.com?foo=bar&" + kw + "=foo" + "&bar_" + kw2 + "=bar",
expected: "https://example.com?foo=bar&" + kw + "=" + mask + "&bar_" + kw2 + "=" + mask,
})
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
masked := MaskSecretURLParams(c.rawURL)
got, err := url.Parse(masked)
require.NoError(t, err)
want, err := url.Parse(c.expected)
require.NoError(t, err)
require.EqualValues(t, got.Query(), want.Query())
require.Equal(t, got.Fragment, want.Fragment)
require.Equal(t, got.Host, want.Host)
require.Equal(t, got.Path, want.Path)
require.Equal(t, got.Scheme, want.Scheme)
})
}
}
func TestMaskURLError(t *testing.T) {
t.Run("not url error", func(t *testing.T) {
e := errors.New("not url.Error")
errStr := e.Error()
masked := MaskURLError(e)
require.Equal(t, e, masked)
require.EqualError(t, masked, errStr)
})
t.Run("no secret in URL", func(t *testing.T) {
e := &url.Error{Op: "GET", URL: "https://example.com?foo=bar", Err: errors.New("not found")}
errStr := e.Error()
masked := MaskURLError(e)
require.Equal(t, e, masked)
require.EqualError(t, masked, errStr)
require.Contains(t, masked.Error(), "?foo=bar")
})
t.Run("masked secret in URL", func(t *testing.T) {
e := &url.Error{Op: "GET", URL: "https://example.com?the_secret=42", Err: errors.New("not found")}
masked := MaskURLError(e)
require.Equal(t, e, masked)
require.EqualError(t, masked, "GET \"https://example.com?the_secret=MASKED\": not found")
require.NotContains(t, masked.Error(), "42")
})
}
func TestBase64DecodePaddingAgnostic(t *testing.T) {
cases := []struct {
in string
want []byte
err error
}{
{"", []byte{}, nil},
{"==", []byte{}, nil},
{"==", []byte{}, nil},
{"dGVzdA==", []byte("test"), nil},
{"dGVzdA", []byte("test"), nil},
{"dGVzdA==ABC", []byte("tes"), base64.CorruptInputError(6)},
}
for _, c := range cases {
got, err := Base64DecodePaddingAgnostic(c.in)
require.Equal(t, c.err, err)
require.Equal(t, got, c.want)
}
}
func TestRemoveDuplicatesFromSlice(t *testing.T) {
tests := map[string]struct {
input []interface{}
output []interface{}
}{
"no duplicates": {
input: []interface{}{34, 56, 1},
output: []interface{}{34, 56, 1},
},
"1 duplicate": {
input: []interface{}{"a", "d", "a"},
output: []interface{}{"a", "d"},
},
"all duplicates": {
input: []interface{}{true, true, true},
output: []interface{}{true},
},
}
for name, test := range tests {
t.Run(
name, func(t *testing.T) {
require.Equal(t, test.output, RemoveDuplicatesFromSlice(test.input))
},
)
}
}
func TestSliceStringsMatch(t *testing.T) {
testCases := []struct {
a, b []string
want bool
name string
}{
{[]string{"foo", "bar"}, []string{"bar", "foo"}, true, "same elements in different order"},
{[]string{"foo", "bar"}, []string{"foo", "bar"}, true, "same elements in same order"},
{[]string{"foo", "bar"}, []string{"bar", "bar"}, false, "different number of same elements"},
{[]string{"foo", "foo", "bar"}, []string{"bar", "foo", "foo"}, true, "both have duplicates"},
{[]string{"foo", "bar", "bar"}, []string{"bar", "foo", "foo"}, false, "both have duplicates but elements don't match"},
{[]string{"foo", "bar"}, []string{"foo"}, false, "different lengths"},
{[]string{}, []string{}, true, "both slices empty"},
{[]string{"foo"}, []string{}, false, "one slice empty"},
{[]string{"unique"}, []string{"unique", "unique"}, false, "duplicate in one slice"},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
got := SliceStringsMatch(tc.a, tc.b)
require.Equal(t, tc.want, got)
})
}
}