2021-07-19 21:20:31 +00:00
|
|
|
package mysql
|
2016-09-22 00:45:57 +00:00
|
|
|
|
|
|
|
import (
|
2021-09-14 12:11:07 +00:00
|
|
|
"context"
|
2020-05-21 15:36:00 +00:00
|
|
|
"encoding/json"
|
2020-05-29 16:12:39 +00:00
|
|
|
"sort"
|
2016-09-22 00:45:57 +00:00
|
|
|
"testing"
|
2021-08-27 14:15:36 +00:00
|
|
|
"time"
|
2016-09-22 00:45:57 +00:00
|
|
|
|
2021-07-19 21:20:31 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/server/ptr"
|
|
|
|
|
2021-06-26 04:46:51 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/server/fleet"
|
2016-09-22 00:45:57 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
2016-12-20 21:54:30 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2016-09-22 00:45:57 +00:00
|
|
|
)
|
|
|
|
|
2021-09-20 18:09:38 +00:00
|
|
|
func TestAppConfig(t *testing.T) {
|
2021-07-19 21:20:31 +00:00
|
|
|
ds := CreateMySQLDS(t)
|
|
|
|
|
2021-09-20 18:09:38 +00:00
|
|
|
cases := []struct {
|
|
|
|
name string
|
|
|
|
fn func(t *testing.T, ds *Datastore)
|
|
|
|
}{
|
|
|
|
{"OrgInfo", testAppConfigOrgInfo},
|
|
|
|
{"AdditionalQueries", testAppConfigAdditionalQueries},
|
|
|
|
{"EnrollSecrets", testAppConfigEnrollSecrets},
|
|
|
|
{"EnrollSecretsCaseSensitive", testAppConfigEnrollSecretsCaseSensitive},
|
|
|
|
{"EnrollSecretRoundtrip", testAppConfigEnrollSecretRoundtrip},
|
|
|
|
{"EnrollSecretUniqueness", testAppConfigEnrollSecretUniqueness},
|
|
|
|
{"Defaults", testAppConfigDefaults},
|
|
|
|
}
|
|
|
|
for _, c := range cases {
|
|
|
|
t.Run(c.name, func(t *testing.T) {
|
|
|
|
c.fn(t, ds)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func testAppConfigOrgInfo(t *testing.T, ds *Datastore) {
|
2021-06-06 22:07:29 +00:00
|
|
|
info := &fleet.AppConfig{
|
2021-08-20 15:27:41 +00:00
|
|
|
OrgInfo: fleet.OrgInfo{
|
|
|
|
OrgName: "Test",
|
|
|
|
OrgLogoURL: "localhost:8080/logo.png",
|
|
|
|
},
|
2016-09-22 00:45:57 +00:00
|
|
|
}
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
info, err := ds.NewAppConfig(context.Background(), info)
|
2016-09-22 00:45:57 +00:00
|
|
|
assert.Nil(t, err)
|
2017-01-11 04:41:58 +00:00
|
|
|
require.NotNil(t, info)
|
2016-09-22 00:45:57 +00:00
|
|
|
|
2021-08-27 14:15:36 +00:00
|
|
|
// Checking some defaults
|
|
|
|
require.Equal(t, 24*time.Hour, info.WebhookSettings.Interval.Duration)
|
|
|
|
require.False(t, info.WebhookSettings.HostStatusWebhook.Enable)
|
2021-09-02 18:59:48 +00:00
|
|
|
require.NotNil(t, info.AgentOptions)
|
2021-08-27 14:15:36 +00:00
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
info2, err := ds.AppConfig(context.Background())
|
2016-12-20 21:54:30 +00:00
|
|
|
require.Nil(t, err)
|
2021-08-20 15:27:41 +00:00
|
|
|
assert.Equal(t, info2.OrgInfo.OrgName, info.OrgInfo.OrgName)
|
|
|
|
smtpConfigured := info2.SMTPSettings.SMTPConfigured
|
|
|
|
assert.False(t, smtpConfigured)
|
|
|
|
|
|
|
|
info2.OrgInfo.OrgName = "testss"
|
|
|
|
info2.SMTPSettings.SMTPDomain = "foo"
|
|
|
|
info2.SMTPSettings.SMTPConfigured = true
|
|
|
|
info2.SMTPSettings.SMTPSenderAddress = "123"
|
|
|
|
info2.SMTPSettings.SMTPServer = "server"
|
|
|
|
info2.SMTPSettings.SMTPPort = 100
|
|
|
|
info2.SMTPSettings.SMTPAuthenticationType = fleet.AuthTypeNameUserNamePassword
|
|
|
|
info2.SMTPSettings.SMTPUserName = "username"
|
|
|
|
info2.SMTPSettings.SMTPPassword = "password"
|
|
|
|
info2.SMTPSettings.SMTPEnableTLS = false
|
|
|
|
info2.SMTPSettings.SMTPAuthenticationMethod = fleet.AuthMethodNameCramMD5
|
|
|
|
info2.SMTPSettings.SMTPVerifySSLCerts = true
|
|
|
|
info2.SMTPSettings.SMTPEnableStartTLS = true
|
|
|
|
info2.SSOSettings.EnableSSO = true
|
|
|
|
info2.SSOSettings.EntityID = "test"
|
|
|
|
info2.SSOSettings.MetadataURL = "https://idp.com/metadata.xml"
|
|
|
|
info2.SSOSettings.IssuerURI = "https://idp.issuer.com"
|
|
|
|
info2.SSOSettings.IDPName = "My IDP"
|
|
|
|
info2.HostSettings.EnableSoftwareInventory = true
|
2017-05-17 15:58:40 +00:00
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
err = ds.SaveAppConfig(context.Background(), info2)
|
2016-12-20 21:54:30 +00:00
|
|
|
require.Nil(t, err)
|
2016-09-22 00:45:57 +00:00
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
info3, err := ds.AppConfig(context.Background())
|
2016-12-20 21:54:30 +00:00
|
|
|
require.Nil(t, err)
|
|
|
|
assert.Equal(t, info2, info3)
|
2016-09-22 00:45:57 +00:00
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
info4, err := ds.NewAppConfig(context.Background(), info3)
|
2016-09-22 00:45:57 +00:00
|
|
|
assert.Nil(t, err)
|
2016-12-20 21:54:30 +00:00
|
|
|
assert.Equal(t, info3, info4)
|
2021-07-09 16:12:21 +00:00
|
|
|
|
|
|
|
email := "e@mail.com"
|
|
|
|
u := &fleet.User{
|
|
|
|
Password: []byte("pass"),
|
|
|
|
Email: email,
|
|
|
|
SSOEnabled: true,
|
2021-07-13 19:33:04 +00:00
|
|
|
GlobalRole: ptr.String(fleet.RoleAdmin),
|
2021-07-09 16:12:21 +00:00
|
|
|
}
|
2021-09-14 12:11:07 +00:00
|
|
|
_, err = ds.NewUser(context.Background(), u)
|
2021-07-09 16:12:21 +00:00
|
|
|
assert.Nil(t, err)
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
verify, err := ds.UserByEmail(context.Background(), email)
|
2021-07-09 16:12:21 +00:00
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.True(t, verify.SSOEnabled)
|
|
|
|
|
2021-08-20 15:27:41 +00:00
|
|
|
info4.SSOSettings.EnableSSO = false
|
2021-09-14 12:11:07 +00:00
|
|
|
err = ds.SaveAppConfig(context.Background(), info4)
|
2021-07-09 16:12:21 +00:00
|
|
|
assert.Nil(t, err)
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
verify, err = ds.UserByEmail(context.Background(), email)
|
2021-07-09 16:12:21 +00:00
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.False(t, verify.SSOEnabled)
|
2016-09-22 00:45:57 +00:00
|
|
|
}
|
2020-05-21 15:36:00 +00:00
|
|
|
|
2021-09-20 18:09:38 +00:00
|
|
|
func testAppConfigAdditionalQueries(t *testing.T, ds *Datastore) {
|
2021-08-20 15:27:41 +00:00
|
|
|
additional := ptr.RawMessage(json.RawMessage("not valid json"))
|
2021-06-06 22:07:29 +00:00
|
|
|
info := &fleet.AppConfig{
|
2021-08-20 15:27:41 +00:00
|
|
|
OrgInfo: fleet.OrgInfo{
|
|
|
|
OrgName: "Test",
|
|
|
|
OrgLogoURL: "localhost:8080/logo.png",
|
|
|
|
},
|
|
|
|
HostSettings: fleet.HostSettings{
|
|
|
|
AdditionalQueries: additional,
|
|
|
|
},
|
2020-05-21 15:36:00 +00:00
|
|
|
}
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
_, err := ds.NewAppConfig(context.Background(), info)
|
2021-08-20 15:27:41 +00:00
|
|
|
require.Error(t, err)
|
2020-05-21 15:36:00 +00:00
|
|
|
|
2021-08-20 15:27:41 +00:00
|
|
|
info.HostSettings.AdditionalQueries = ptr.RawMessage(json.RawMessage(`{}`))
|
2021-09-14 12:11:07 +00:00
|
|
|
info, err = ds.NewAppConfig(context.Background(), info)
|
2021-08-20 15:27:41 +00:00
|
|
|
require.NoError(t, err)
|
2020-05-21 15:36:00 +00:00
|
|
|
|
2021-08-20 15:27:41 +00:00
|
|
|
info.HostSettings.AdditionalQueries = ptr.RawMessage(json.RawMessage(`{"foo": "bar"}`))
|
2021-09-14 12:11:07 +00:00
|
|
|
info, err = ds.NewAppConfig(context.Background(), info)
|
2021-08-20 15:27:41 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
rawJson := *info.HostSettings.AdditionalQueries
|
|
|
|
assert.JSONEq(t, `{"foo":"bar"}`, string(rawJson))
|
2020-05-21 15:36:00 +00:00
|
|
|
}
|
2020-05-29 16:12:39 +00:00
|
|
|
|
2021-09-20 18:09:38 +00:00
|
|
|
func testAppConfigEnrollSecrets(t *testing.T, ds *Datastore) {
|
|
|
|
defer TruncateTables(t, ds)
|
2021-07-19 21:20:31 +00:00
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
team1, err := ds.NewTeam(context.Background(), &fleet.Team{Name: "team1"})
|
2021-05-31 16:02:05 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
secret, err := ds.VerifyEnrollSecret(context.Background(), "missing")
|
2020-05-29 16:12:39 +00:00
|
|
|
assert.Error(t, err)
|
2021-05-31 16:02:05 +00:00
|
|
|
assert.Nil(t, secret)
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
err = ds.ApplyEnrollSecrets(context.Background(), &team1.ID,
|
2021-06-06 22:07:29 +00:00
|
|
|
[]*fleet.EnrollSecret{
|
2021-05-31 16:02:05 +00:00
|
|
|
{Secret: "one_secret", TeamID: &team1.ID},
|
2020-05-29 16:12:39 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
secret, err = ds.VerifyEnrollSecret(context.Background(), "one")
|
2020-05-29 16:12:39 +00:00
|
|
|
assert.Error(t, err, "secret should not match")
|
2021-05-31 16:02:05 +00:00
|
|
|
assert.Nil(t, secret, "secret should be nil")
|
2021-09-14 12:11:07 +00:00
|
|
|
secret, err = ds.VerifyEnrollSecret(context.Background(), "one_secret")
|
2020-05-29 16:12:39 +00:00
|
|
|
assert.NoError(t, err)
|
2021-05-31 16:02:05 +00:00
|
|
|
assert.Equal(t, &team1.ID, secret.TeamID)
|
2021-09-14 12:11:07 +00:00
|
|
|
secret, err = ds.VerifyEnrollSecret(context.Background(), "two_secret")
|
2020-05-29 16:12:39 +00:00
|
|
|
assert.Error(t, err)
|
2021-05-31 16:02:05 +00:00
|
|
|
assert.Nil(t, secret)
|
|
|
|
|
|
|
|
// Add global secret
|
|
|
|
err = ds.ApplyEnrollSecrets(
|
2021-09-14 12:11:07 +00:00
|
|
|
context.Background(),
|
2021-05-31 16:02:05 +00:00
|
|
|
nil,
|
2021-06-06 22:07:29 +00:00
|
|
|
[]*fleet.EnrollSecret{
|
2021-05-31 16:02:05 +00:00
|
|
|
{Secret: "two_secret"},
|
2020-05-29 16:12:39 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
secret, err = ds.VerifyEnrollSecret(context.Background(), "one_secret")
|
2021-05-31 16:02:05 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, &team1.ID, secret.TeamID)
|
2021-09-14 12:11:07 +00:00
|
|
|
secret, err = ds.VerifyEnrollSecret(context.Background(), "two_secret")
|
2021-05-31 16:02:05 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, (*uint)(nil), secret.TeamID)
|
|
|
|
|
|
|
|
// Remove team secret
|
2021-09-14 12:11:07 +00:00
|
|
|
err = ds.ApplyEnrollSecrets(context.Background(), &team1.ID, []*fleet.EnrollSecret{})
|
2021-05-31 16:02:05 +00:00
|
|
|
assert.NoError(t, err)
|
2021-09-14 12:11:07 +00:00
|
|
|
secret, err = ds.VerifyEnrollSecret(context.Background(), "one_secret")
|
2020-05-29 16:12:39 +00:00
|
|
|
assert.Error(t, err)
|
2021-05-31 16:02:05 +00:00
|
|
|
assert.Nil(t, secret)
|
2021-09-14 12:11:07 +00:00
|
|
|
secret, err = ds.VerifyEnrollSecret(context.Background(), "two_secret")
|
2020-05-29 16:12:39 +00:00
|
|
|
assert.NoError(t, err)
|
2021-05-31 16:02:05 +00:00
|
|
|
assert.Equal(t, (*uint)(nil), secret.TeamID)
|
2020-11-04 20:09:00 +00:00
|
|
|
}
|
|
|
|
|
2021-09-20 18:09:38 +00:00
|
|
|
func testAppConfigEnrollSecretsCaseSensitive(t *testing.T, ds *Datastore) {
|
|
|
|
defer TruncateTables(t, ds)
|
2021-07-19 21:20:31 +00:00
|
|
|
|
2021-05-31 16:02:05 +00:00
|
|
|
err := ds.ApplyEnrollSecrets(
|
2021-09-14 12:11:07 +00:00
|
|
|
context.Background(),
|
2021-05-31 16:02:05 +00:00
|
|
|
nil,
|
2021-06-06 22:07:29 +00:00
|
|
|
[]*fleet.EnrollSecret{
|
2021-05-31 16:02:05 +00:00
|
|
|
{Secret: "one_secret"},
|
2020-11-04 20:09:00 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
require.NoError(t, err)
|
2020-05-29 16:12:39 +00:00
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
_, err = ds.VerifyEnrollSecret(context.Background(), "one_secret")
|
2020-11-04 20:09:00 +00:00
|
|
|
assert.NoError(t, err, "enroll secret should match with matching case")
|
2021-09-14 12:11:07 +00:00
|
|
|
_, err = ds.VerifyEnrollSecret(context.Background(), "One_Secret")
|
2020-11-04 20:09:00 +00:00
|
|
|
assert.Error(t, err, "enroll secret with different case should not verify")
|
2020-05-29 16:12:39 +00:00
|
|
|
}
|
|
|
|
|
2021-09-20 18:09:38 +00:00
|
|
|
func testAppConfigEnrollSecretRoundtrip(t *testing.T, ds *Datastore) {
|
|
|
|
defer TruncateTables(t, ds)
|
2021-07-19 21:20:31 +00:00
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
team1, err := ds.NewTeam(context.Background(), &fleet.Team{Name: "team1"})
|
2020-05-29 16:12:39 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
secrets, err := ds.GetEnrollSecrets(context.Background(), nil)
|
2021-05-31 16:02:05 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Len(t, secrets, 0)
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
secrets, err = ds.GetEnrollSecrets(context.Background(), &team1.ID)
|
2021-05-31 16:02:05 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Len(t, secrets, 0)
|
|
|
|
|
2021-06-06 22:07:29 +00:00
|
|
|
expectedSecrets := []*fleet.EnrollSecret{
|
2021-05-31 16:02:05 +00:00
|
|
|
{Secret: "one_secret"},
|
|
|
|
{Secret: "two_secret"},
|
2020-05-29 16:12:39 +00:00
|
|
|
}
|
2021-09-14 12:11:07 +00:00
|
|
|
err = ds.ApplyEnrollSecrets(context.Background(), &team1.ID, expectedSecrets)
|
2020-05-29 16:12:39 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
secrets, err = ds.GetEnrollSecrets(context.Background(), &team1.ID)
|
2020-05-29 16:12:39 +00:00
|
|
|
require.NoError(t, err)
|
2021-05-31 16:02:05 +00:00
|
|
|
require.Len(t, secrets, 2)
|
2020-05-29 16:12:39 +00:00
|
|
|
// sort secrets before equality checks to ensure proper order
|
2021-05-31 16:02:05 +00:00
|
|
|
sort.Slice(secrets, func(i, j int) bool { return secrets[i].Secret < secrets[j].Secret })
|
|
|
|
|
|
|
|
assert.Equal(t, "one_secret", secrets[0].Secret)
|
|
|
|
assert.Equal(t, "two_secret", secrets[1].Secret)
|
|
|
|
|
|
|
|
expectedSecrets[0].Secret += "_global"
|
|
|
|
expectedSecrets[1].Secret += "_global"
|
2021-09-14 12:11:07 +00:00
|
|
|
err = ds.ApplyEnrollSecrets(context.Background(), nil, expectedSecrets)
|
2021-05-31 16:02:05 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
secrets, err = ds.GetEnrollSecrets(context.Background(), nil)
|
2021-05-31 16:02:05 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, secrets, 2)
|
2020-05-29 16:12:39 +00:00
|
|
|
|
2021-05-31 16:02:05 +00:00
|
|
|
}
|
|
|
|
|
2021-09-20 18:09:38 +00:00
|
|
|
func testAppConfigEnrollSecretUniqueness(t *testing.T, ds *Datastore) {
|
|
|
|
defer TruncateTables(t, ds)
|
2021-07-19 21:20:31 +00:00
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
team1, err := ds.NewTeam(context.Background(), &fleet.Team{Name: "team1"})
|
2021-05-31 16:02:05 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2021-06-06 22:07:29 +00:00
|
|
|
expectedSecrets := []*fleet.EnrollSecret{
|
2021-05-31 16:02:05 +00:00
|
|
|
{Secret: "one_secret"},
|
|
|
|
}
|
2021-09-14 12:11:07 +00:00
|
|
|
err = ds.ApplyEnrollSecrets(context.Background(), &team1.ID, expectedSecrets)
|
2021-05-31 16:02:05 +00:00
|
|
|
require.NoError(t, err)
|
2020-05-29 16:12:39 +00:00
|
|
|
|
2021-05-31 16:02:05 +00:00
|
|
|
// Same secret at global level should not be allowed
|
2021-09-14 12:11:07 +00:00
|
|
|
err = ds.ApplyEnrollSecrets(context.Background(), nil, expectedSecrets)
|
2021-05-31 16:02:05 +00:00
|
|
|
require.Error(t, err)
|
2020-05-29 16:12:39 +00:00
|
|
|
}
|
2021-08-27 14:15:36 +00:00
|
|
|
|
2021-09-20 18:09:38 +00:00
|
|
|
func testAppConfigDefaults(t *testing.T, ds *Datastore) {
|
2021-08-27 14:15:36 +00:00
|
|
|
insertAppConfigQuery := `INSERT INTO app_config_json(json_value) VALUES(?) ON DUPLICATE KEY UPDATE json_value = VALUES(json_value)`
|
2021-09-01 19:50:52 +00:00
|
|
|
_, err := ds.writer.Exec(insertAppConfigQuery, `{}`)
|
2021-08-27 14:15:36 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
ac, err := ds.AppConfig(context.Background())
|
2021-08-27 14:15:36 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, 24*time.Hour, ac.WebhookSettings.Interval.Duration)
|
|
|
|
require.False(t, ac.WebhookSettings.HostStatusWebhook.Enable)
|
|
|
|
require.True(t, ac.HostSettings.EnableHostUsers)
|
|
|
|
require.False(t, ac.HostSettings.EnableSoftwareInventory)
|
|
|
|
|
2021-09-01 19:50:52 +00:00
|
|
|
_, err = ds.writer.Exec(
|
2021-08-27 14:15:36 +00:00
|
|
|
insertAppConfigQuery,
|
|
|
|
`{"webhook_settings": {"interval": "12h"}, "host_settings": {"enable_host_users": false}}`,
|
|
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2021-09-14 12:11:07 +00:00
|
|
|
ac, err = ds.AppConfig(context.Background())
|
2021-08-27 14:15:36 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
require.Equal(t, 12*time.Hour, ac.WebhookSettings.Interval.Duration)
|
|
|
|
require.False(t, ac.HostSettings.EnableHostUsers)
|
|
|
|
require.False(t, ac.HostSettings.EnableSoftwareInventory)
|
|
|
|
}
|