Do not return empty SSO and SMTP settings for non-global-admins (#12180)
#11266 PS: I first attempted a serialization trick by introducing a new `appConfigResponse` and implementing `json.Marshal` to exclude these fields but it was too hacky and hard to maintain moving forward, so I'm bitting the bullet now. Happy to hear other ideas. - [X] Changes file added for user-visible changes in `changes/` or `orbit/changes/`. See [Changes files](https://fleetdm.com/docs/contributing/committing-changes#changes-files) for more information. - ~[ ] Documented any API changes (docs/Using-Fleet/REST-API.md or docs/Contributing/API-for-contributors.md)~ - ~[ ] Documented any permissions changes~ - ~[ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements)~ - ~[ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for new osquery data ingestion features.~ - [X] Added/updated tests - [X] Manual QA for all new/changed functionality - ~For Orbit and Fleet Desktop changes:~ - ~[ ] Manual QA must be performed in the three main OSs, macOS, Windows and Linux.~ - ~[ ] Auto-update manual QA, from released version of component to new version (see [tools/tuf/test](../tools/tuf/test/README.md)).~
This commit is contained in:
@@ -63,7 +63,7 @@ func (ds *Datastore) SaveAppConfig(ctx context.Context, info *fleet.AppConfig) e
|
||||
return ctxerr.Wrap(ctx, err, "insert app_config_json")
|
||||
}
|
||||
|
||||
if !info.SSOSettings.EnableSSO {
|
||||
if info.SSOSettings != nil && !info.SSOSettings.EnableSSO {
|
||||
_, err = tx.ExecContext(ctx, `UPDATE users SET sso_enabled=false`)
|
||||
if err != nil {
|
||||
return ctxerr.Wrap(ctx, err, "update users sso")
|
||||
|
||||
+51
-20
@@ -308,22 +308,35 @@ type MDMEndUserAuthentication struct {
|
||||
SSOProviderSettings
|
||||
}
|
||||
|
||||
// AppConfig holds server configuration that can be changed via the API.
|
||||
// AppConfig holds global server configuration that can be changed via the API.
|
||||
//
|
||||
// Note: management of deprecated fields is done on JSON-marshalling and uses
|
||||
// the legacyConfig struct to list them.
|
||||
//
|
||||
// ///////////////////////////////////////////////////////////////
|
||||
// WARNING: If you add or change fields of this struct make sure
|
||||
// it's taken into account in the AppConfig Clone implementation!
|
||||
// ///////////////////////////////////////////////////////////////
|
||||
type AppConfig struct {
|
||||
OrgInfo OrgInfo `json:"org_info"`
|
||||
ServerSettings ServerSettings `json:"server_settings"`
|
||||
SMTPSettings SMTPSettings `json:"smtp_settings"`
|
||||
OrgInfo OrgInfo `json:"org_info"`
|
||||
ServerSettings ServerSettings `json:"server_settings"`
|
||||
// SMTPSettings holds the SMTP integration settings.
|
||||
//
|
||||
// This field is a pointer to avoid returning this information to non-global-admins.
|
||||
SMTPSettings *SMTPSettings `json:"smtp_settings,omitempty"`
|
||||
HostExpirySettings HostExpirySettings `json:"host_expiry_settings"`
|
||||
// Features allows to globally enable or disable features
|
||||
Features Features `json:"features"`
|
||||
Features Features `json:"features"`
|
||||
// AgentOptions holds osquery configuration.
|
||||
//
|
||||
// This field is a pointer to avoid returning this information to non-global-admins.
|
||||
AgentOptions *json.RawMessage `json:"agent_options,omitempty"`
|
||||
// SMTPTest is a flag that if set will cause the server to test email configuration
|
||||
SMTPTest bool `json:"smtp_test,omitempty"`
|
||||
// SSOSettings is single sign on settings
|
||||
SSOSettings SSOSettings `json:"sso_settings"`
|
||||
// SSOSettings is single sign on integration settings.
|
||||
//
|
||||
// This field is a pointer to avoid returning this information to non-global-admins.
|
||||
SSOSettings *SSOSettings `json:"sso_settings,omitempty"`
|
||||
// FleetDesktop holds settings for Fleet Desktop that can be changed via the API.
|
||||
FleetDesktop FleetDesktopSettings `json:"fleet_desktop"`
|
||||
|
||||
@@ -342,15 +355,15 @@ type AppConfig struct {
|
||||
// if any legacy settings were set in the raw JSON.
|
||||
didUnmarshalLegacySettings []string
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// WARNING: If you add to this struct make sure it's taken into
|
||||
// account in the AppConfig Clone implementation!
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// ///////////////////////////////////////////////////////////////
|
||||
// WARNING: If you add or change fields of this struct make sure
|
||||
// it's taken into account in the AppConfig Clone implementation!
|
||||
// ///////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
// Obfuscate overrides credentials with obfuscated characters.
|
||||
func (c *AppConfig) Obfuscate() {
|
||||
if c.SMTPSettings.SMTPPassword != "" {
|
||||
if c.SMTPSettings != nil && c.SMTPSettings.SMTPPassword != "" {
|
||||
c.SMTPSettings.SMTPPassword = MaskedPassword
|
||||
}
|
||||
for _, jiraIntegration := range c.Integrations.Jira {
|
||||
@@ -389,7 +402,12 @@ func (c *AppConfig) Copy() *AppConfig {
|
||||
copy(clone.ServerSettings.DebugHostIDs, c.ServerSettings.DebugHostIDs)
|
||||
}
|
||||
|
||||
// SMTPSettings: nothing needs cloning
|
||||
if c.SMTPSettings != nil {
|
||||
var smtpSettings SMTPSettings
|
||||
smtpSettings = *c.SMTPSettings
|
||||
clone.SMTPSettings = &smtpSettings
|
||||
}
|
||||
|
||||
// HostExpirySettings: nothing needs cloning
|
||||
|
||||
if c.Features.AdditionalQueries != nil {
|
||||
@@ -403,7 +421,12 @@ func (c *AppConfig) Copy() *AppConfig {
|
||||
clone.AgentOptions = &ao
|
||||
}
|
||||
|
||||
// SSOSettings: nothing needs cloning
|
||||
if c.SSOSettings != nil {
|
||||
var ssoSettings SSOSettings
|
||||
ssoSettings = *c.SSOSettings
|
||||
clone.SSOSettings = &ssoSettings
|
||||
}
|
||||
|
||||
// FleetDesktop: nothing needs cloning
|
||||
// VulnerabilitySettings: nothing needs cloning
|
||||
|
||||
@@ -548,16 +571,24 @@ type VulnerabilitiesWebhookSettings struct {
|
||||
func (c *AppConfig) ApplyDefaultsForNewInstalls() {
|
||||
c.ServerSettings.EnableAnalytics = true
|
||||
|
||||
c.SMTPSettings.SMTPPort = 587
|
||||
c.SMTPSettings.SMTPEnableStartTLS = true
|
||||
c.SMTPSettings.SMTPAuthenticationType = AuthTypeNameUserNamePassword
|
||||
c.SMTPSettings.SMTPAuthenticationMethod = AuthMethodNamePlain
|
||||
c.SMTPSettings.SMTPVerifySSLCerts = true
|
||||
c.SMTPSettings.SMTPEnableTLS = true
|
||||
// Add default values for SMTPSettings.
|
||||
var smtpSettings SMTPSettings
|
||||
smtpSettings.SMTPEnabled = false
|
||||
smtpSettings.SMTPPort = 587
|
||||
smtpSettings.SMTPEnableStartTLS = true
|
||||
smtpSettings.SMTPAuthenticationType = AuthTypeNameUserNamePassword
|
||||
smtpSettings.SMTPAuthenticationMethod = AuthMethodNamePlain
|
||||
smtpSettings.SMTPVerifySSLCerts = true
|
||||
smtpSettings.SMTPEnableTLS = true
|
||||
c.SMTPSettings = &smtpSettings
|
||||
|
||||
agentOptions := json.RawMessage(`{"config": {"options": {"pack_delimiter": "/", "logger_tls_period": 10, "distributed_plugin": "tls", "disable_distributed": false, "logger_tls_endpoint": "/api/osquery/log", "distributed_interval": 10, "distributed_tls_max_attempts": 3}, "decorators": {"load": ["SELECT uuid AS host_uuid FROM system_info;", "SELECT hostname AS hostname FROM system_info;"]}}, "overrides": {}}`)
|
||||
c.AgentOptions = &agentOptions
|
||||
|
||||
// Make sure an empty SSOSettings is set.
|
||||
var ssoSettings SSOSettings
|
||||
c.SSOSettings = &ssoSettings
|
||||
|
||||
c.Features.ApplyDefaultsForNewInstalls()
|
||||
|
||||
c.ApplyDefaults()
|
||||
|
||||
@@ -12,10 +12,11 @@ type Mailer interface {
|
||||
}
|
||||
|
||||
type Email struct {
|
||||
Subject string
|
||||
To []string
|
||||
Config *AppConfig
|
||||
Mailer Mailer
|
||||
Subject string
|
||||
To []string
|
||||
ServerURL string
|
||||
SMTPSettings SMTPSettings
|
||||
Mailer Mailer
|
||||
}
|
||||
|
||||
type MailService interface {
|
||||
|
||||
+14
-14
@@ -75,11 +75,11 @@ func getMessageBody(e fleet.Email, f fromFunc) ([]byte, error) {
|
||||
}
|
||||
|
||||
func getFrom(e fleet.Email) (string, error) {
|
||||
return "From: " + e.Config.SMTPSettings.SMTPSenderAddress + "\r\n", nil
|
||||
return "From: " + e.SMTPSettings.SMTPSenderAddress + "\r\n", nil
|
||||
}
|
||||
|
||||
func (m mailService) SendEmail(e fleet.Email) error {
|
||||
if !e.Config.SMTPSettings.SMTPConfigured {
|
||||
if !e.SMTPSettings.SMTPConfigured {
|
||||
return errors.New("email not configured")
|
||||
}
|
||||
msg, err := getMessageBody(e, getFrom)
|
||||
@@ -132,14 +132,14 @@ func (l *loginauth) Next(fromServer []byte, more bool) (toServer []byte, err err
|
||||
}
|
||||
|
||||
func smtpAuth(e fleet.Email) (smtp.Auth, error) {
|
||||
if e.Config.SMTPSettings.SMTPAuthenticationType != fleet.AuthTypeNameUserNamePassword {
|
||||
if e.SMTPSettings.SMTPAuthenticationType != fleet.AuthTypeNameUserNamePassword {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
username := e.Config.SMTPSettings.SMTPUserName
|
||||
password := e.Config.SMTPSettings.SMTPPassword
|
||||
server := e.Config.SMTPSettings.SMTPServer
|
||||
authMethod := e.Config.SMTPSettings.SMTPAuthenticationMethod
|
||||
username := e.SMTPSettings.SMTPUserName
|
||||
password := e.SMTPSettings.SMTPPassword
|
||||
server := e.SMTPSettings.SMTPServer
|
||||
authMethod := e.SMTPSettings.SMTPAuthenticationMethod
|
||||
|
||||
var auth smtp.Auth
|
||||
switch authMethod {
|
||||
@@ -157,14 +157,14 @@ func smtpAuth(e fleet.Email) (smtp.Auth, error) {
|
||||
|
||||
func (m mailService) sendMail(e fleet.Email, msg []byte) error {
|
||||
smtpHost := fmt.Sprintf(
|
||||
"%s:%d", e.Config.SMTPSettings.SMTPServer, e.Config.SMTPSettings.SMTPPort)
|
||||
"%s:%d", e.SMTPSettings.SMTPServer, e.SMTPSettings.SMTPPort)
|
||||
auth, err := smtpAuth(e)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get smtp auth: %w", err)
|
||||
}
|
||||
|
||||
if e.Config.SMTPSettings.SMTPAuthenticationMethod == fleet.AuthMethodNameCramMD5 {
|
||||
err = smtp.SendMail(smtpHost, auth, e.Config.SMTPSettings.SMTPSenderAddress, e.To, msg)
|
||||
if e.SMTPSettings.SMTPAuthenticationMethod == fleet.AuthMethodNameCramMD5 {
|
||||
err = smtp.SendMail(smtpHost, auth, e.SMTPSettings.SMTPSenderAddress, e.To, msg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to send mail. crammd5 auth method: %w", err)
|
||||
}
|
||||
@@ -177,11 +177,11 @@ func (m mailService) sendMail(e fleet.Email, msg []byte) error {
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
if e.Config.SMTPSettings.SMTPEnableStartTLS {
|
||||
if e.SMTPSettings.SMTPEnableStartTLS {
|
||||
if ok, _ := client.Extension("STARTTLS"); ok {
|
||||
config := &tls.Config{
|
||||
ServerName: e.Config.SMTPSettings.SMTPServer,
|
||||
InsecureSkipVerify: !e.Config.SMTPSettings.SMTPVerifySSLCerts,
|
||||
ServerName: e.SMTPSettings.SMTPServer,
|
||||
InsecureSkipVerify: !e.SMTPSettings.SMTPVerifySSLCerts,
|
||||
}
|
||||
if err = client.StartTLS(config); err != nil {
|
||||
return fmt.Errorf("startTLS error: %w", err)
|
||||
@@ -193,7 +193,7 @@ func (m mailService) sendMail(e fleet.Email, msg []byte) error {
|
||||
return fmt.Errorf("client auth error: %w", err)
|
||||
}
|
||||
}
|
||||
if err = client.Mail(e.Config.SMTPSettings.SMTPSenderAddress); err != nil {
|
||||
if err = client.Mail(e.SMTPSettings.SMTPSenderAddress); err != nil {
|
||||
return fmt.Errorf("could not issue mail to provided address: %w", err)
|
||||
}
|
||||
for _, recip := range e.To {
|
||||
|
||||
+63
-67
@@ -41,20 +41,18 @@ func testSMTPPlainAuth(t *testing.T, mailer fleet.MailService) {
|
||||
mail := fleet.Email{
|
||||
Subject: "smtp plain auth",
|
||||
To: []string{"john@fleet.co"},
|
||||
Config: &fleet.AppConfig{
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameUserNamePassword,
|
||||
SMTPAuthenticationMethod: fleet.AuthMethodNamePlain,
|
||||
SMTPUserName: "mailpit-username",
|
||||
SMTPPassword: "mailpit-password",
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: true,
|
||||
SMTPEnableStartTLS: true,
|
||||
SMTPPort: 1026,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
},
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameUserNamePassword,
|
||||
SMTPAuthenticationMethod: fleet.AuthMethodNamePlain,
|
||||
SMTPUserName: "mailpit-username",
|
||||
SMTPPassword: "mailpit-password",
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: true,
|
||||
SMTPEnableStartTLS: true,
|
||||
SMTPPort: 1026,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
},
|
||||
Mailer: &SMTPTestMailer{
|
||||
BaseURL: "https://localhost:8080",
|
||||
@@ -69,20 +67,18 @@ func testSMTPPlainAuthInvalidCreds(t *testing.T, mailer fleet.MailService) {
|
||||
mail := fleet.Email{
|
||||
Subject: "smtp plain auth with invalid credentials",
|
||||
To: []string{"john@fleet.co"},
|
||||
Config: &fleet.AppConfig{
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameUserNamePassword,
|
||||
SMTPAuthenticationMethod: fleet.AuthMethodNamePlain,
|
||||
SMTPUserName: "mailpit-username",
|
||||
SMTPPassword: "wrong",
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: true,
|
||||
SMTPEnableStartTLS: true,
|
||||
SMTPPort: 1026,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
},
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameUserNamePassword,
|
||||
SMTPAuthenticationMethod: fleet.AuthMethodNamePlain,
|
||||
SMTPUserName: "mailpit-username",
|
||||
SMTPPassword: "wrong",
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: true,
|
||||
SMTPEnableStartTLS: true,
|
||||
SMTPPort: 1026,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
},
|
||||
Mailer: &SMTPTestMailer{
|
||||
BaseURL: "https://localhost:8080",
|
||||
@@ -97,20 +93,18 @@ func testSMTPSkipVerify(t *testing.T, mailer fleet.MailService) {
|
||||
mail := fleet.Email{
|
||||
Subject: "skip verify",
|
||||
To: []string{"john@fleet.co"},
|
||||
Config: &fleet.AppConfig{
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameUserNamePassword,
|
||||
SMTPAuthenticationMethod: fleet.AuthMethodNamePlain,
|
||||
SMTPUserName: "mailpit-username",
|
||||
SMTPPassword: "mailpit-password",
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: false,
|
||||
SMTPEnableStartTLS: true,
|
||||
SMTPPort: 1025,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
},
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameUserNamePassword,
|
||||
SMTPAuthenticationMethod: fleet.AuthMethodNamePlain,
|
||||
SMTPUserName: "mailpit-username",
|
||||
SMTPPassword: "mailpit-password",
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: false,
|
||||
SMTPEnableStartTLS: true,
|
||||
SMTPPort: 1025,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
},
|
||||
Mailer: &SMTPTestMailer{
|
||||
BaseURL: "https://localhost:8080",
|
||||
@@ -125,16 +119,14 @@ func testSMTPNoAuth(t *testing.T, mailer fleet.MailService) {
|
||||
mail := fleet.Email{
|
||||
Subject: "no auth",
|
||||
To: []string{"bob@foo.com"},
|
||||
Config: &fleet.AppConfig{
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameNone,
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: true,
|
||||
SMTPPort: 1025,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
},
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameNone,
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: true,
|
||||
SMTPPort: 1025,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
},
|
||||
Mailer: &SMTPTestMailer{
|
||||
BaseURL: "https://localhost:8080",
|
||||
@@ -149,19 +141,17 @@ func testMailTest(t *testing.T, mailer fleet.MailService) {
|
||||
mail := fleet.Email{
|
||||
Subject: "test tester",
|
||||
To: []string{"bob@foo.com"},
|
||||
Config: &fleet.AppConfig{
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameUserNamePassword,
|
||||
SMTPAuthenticationMethod: fleet.AuthMethodNamePlain,
|
||||
SMTPUserName: "mailpit-username",
|
||||
SMTPPassword: "mailpit-password",
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: true,
|
||||
SMTPPort: 1026,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
},
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameUserNamePassword,
|
||||
SMTPAuthenticationMethod: fleet.AuthMethodNamePlain,
|
||||
SMTPUserName: "mailpit-username",
|
||||
SMTPPassword: "mailpit-password",
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: true,
|
||||
SMTPPort: 1026,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
},
|
||||
Mailer: &SMTPTestMailer{
|
||||
BaseURL: "https://localhost:8080",
|
||||
@@ -193,8 +183,14 @@ func Test_getFrom(t *testing.T) {
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "should return SMTP formatted From string",
|
||||
args: args{e: fleet.Email{Config: &fleet.AppConfig{SMTPSettings: fleet.SMTPSettings{SMTPSenderAddress: "foo@bar.com"}}}},
|
||||
name: "should return SMTP formatted From string",
|
||||
args: args{
|
||||
e: fleet.Email{
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPSenderAddress: "foo@bar.com",
|
||||
},
|
||||
},
|
||||
},
|
||||
want: "From: foo@bar.com\r\n",
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
|
||||
+2
-6
@@ -23,12 +23,9 @@ type sesSender struct {
|
||||
}
|
||||
|
||||
func getFromSES(e fleet.Email) (string, error) {
|
||||
if e.Config == nil {
|
||||
return "", errors.New("app config is nil")
|
||||
}
|
||||
serverURL, err := url.Parse(e.Config.ServerSettings.ServerURL)
|
||||
serverURL, err := url.Parse(e.ServerURL)
|
||||
if err != nil || len(serverURL.Host) == 0 {
|
||||
return "", fmt.Errorf("failed to parse server url %s err: %w", e.Config.ServerSettings.ServerURL, err)
|
||||
return "", fmt.Errorf("failed to parse server url %s err: %w", e.ServerURL, err)
|
||||
}
|
||||
return fmt.Sprintf("From: %s\r\n", fmt.Sprintf("do-not-reply@%s", serverURL.Host)), nil
|
||||
}
|
||||
@@ -87,7 +84,6 @@ func (s *sesSender) sendMail(e fleet.Email, msg []byte) error {
|
||||
RawMessage: &ses.RawMessage{Data: msg},
|
||||
SourceArn: &s.sourceArn,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+17
-14
@@ -21,14 +21,18 @@ func Test_getFromSES(t *testing.T) {
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "should return properly formatted SMTP from for use in SES",
|
||||
args: args{e: fleet.Email{Config: &fleet.AppConfig{ServerSettings: fleet.ServerSettings{ServerURL: "https://foobar.fleetdm.com"}}}},
|
||||
name: "should return properly formatted SMTP from for use in SES",
|
||||
args: args{e: fleet.Email{
|
||||
ServerURL: "https://foobar.fleetdm.com",
|
||||
}},
|
||||
want: "From: do-not-reply@foobar.fleetdm.com\r\n",
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "should error when we fail to parse fleet server url",
|
||||
args: args{e: fleet.Email{Config: &fleet.AppConfig{ServerSettings: fleet.ServerSettings{ServerURL: "not-a-url"}}}},
|
||||
name: "should error when we fail to parse fleet server url",
|
||||
args: args{e: fleet.Email{
|
||||
ServerURL: "not-a-url",
|
||||
}},
|
||||
want: "",
|
||||
wantErr: assert.Error,
|
||||
},
|
||||
@@ -76,9 +80,9 @@ func Test_sesSender_SendEmail(t *testing.T) {
|
||||
sourceArn: "foo",
|
||||
},
|
||||
args: args{e: fleet.Email{
|
||||
Subject: "Hello from Fleet!",
|
||||
To: []string{"foouser@fleetdm.com"},
|
||||
Config: &fleet.AppConfig{ServerSettings: fleet.ServerSettings{ServerURL: "https://foobar.fleetdm.com"}},
|
||||
Subject: "Hello from Fleet!",
|
||||
To: []string{"foouser@fleetdm.com"},
|
||||
ServerURL: "https://foobar.fleetdm.com",
|
||||
Mailer: &SMTPTestMailer{
|
||||
BaseURL: "https://localhost:8080",
|
||||
},
|
||||
@@ -94,7 +98,6 @@ func Test_sesSender_SendEmail(t *testing.T) {
|
||||
args: args{e: fleet.Email{
|
||||
Subject: "Hello from Fleet!",
|
||||
To: []string{"foouser@fleetdm.com"},
|
||||
Config: nil,
|
||||
Mailer: &SMTPTestMailer{
|
||||
BaseURL: "https://localhost:8080",
|
||||
},
|
||||
@@ -108,9 +111,9 @@ func Test_sesSender_SendEmail(t *testing.T) {
|
||||
sourceArn: "foo",
|
||||
},
|
||||
args: args{e: fleet.Email{
|
||||
Subject: "Hello from Fleet!",
|
||||
To: []string{"foouser@fleetdm.com"},
|
||||
Config: &fleet.AppConfig{ServerSettings: fleet.ServerSettings{ServerURL: "https://foobar.fleetdm.com"}},
|
||||
Subject: "Hello from Fleet!",
|
||||
To: []string{"foouser@fleetdm.com"},
|
||||
ServerURL: "https://foobar.fleetdm.com",
|
||||
Mailer: &SMTPTestMailer{
|
||||
BaseURL: "https://localhost:8080",
|
||||
},
|
||||
@@ -124,9 +127,9 @@ func Test_sesSender_SendEmail(t *testing.T) {
|
||||
sourceArn: "foo",
|
||||
},
|
||||
args: args{e: fleet.Email{
|
||||
Subject: "Hello from Fleet!",
|
||||
To: []string{"foouser@fleetdm.com"},
|
||||
Config: &fleet.AppConfig{ServerSettings: fleet.ServerSettings{ServerURL: "https://foobar.fleetdm.com"}},
|
||||
Subject: "Hello from Fleet!",
|
||||
To: []string{"foouser@fleetdm.com"},
|
||||
ServerURL: "https://foobar.fleetdm.com",
|
||||
Mailer: &SMTPTestMailer{
|
||||
BaseURL: "https://localhost:8080",
|
||||
},
|
||||
|
||||
+43
-29
@@ -98,15 +98,13 @@ func getAppConfigEndpoint(ctx context.Context, request interface{}, svc fleet.Se
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var smtpSettings fleet.SMTPSettings
|
||||
var ssoSettings fleet.SSOSettings
|
||||
var hostExpirySettings fleet.HostExpirySettings
|
||||
// Only the Global Admin should be able to see see SMTP, SSO and osquery agent settings.
|
||||
var smtpSettings *fleet.SMTPSettings
|
||||
var ssoSettings *fleet.SSOSettings
|
||||
var agentOptions *json.RawMessage
|
||||
// only admin can see smtp, sso, and host expiry settings
|
||||
if vc.User.GlobalRole != nil && *vc.User.GlobalRole == fleet.RoleAdmin {
|
||||
smtpSettings = config.SMTPSettings
|
||||
ssoSettings = config.SSOSettings
|
||||
hostExpirySettings = config.HostExpirySettings
|
||||
agentOptions = config.AgentOptions
|
||||
}
|
||||
|
||||
@@ -128,11 +126,11 @@ func getAppConfigEndpoint(ctx context.Context, request interface{}, svc fleet.Se
|
||||
ServerSettings: config.ServerSettings,
|
||||
Features: features,
|
||||
VulnerabilitySettings: config.VulnerabilitySettings,
|
||||
HostExpirySettings: config.HostExpirySettings,
|
||||
|
||||
SMTPSettings: smtpSettings,
|
||||
SSOSettings: ssoSettings,
|
||||
HostExpirySettings: hostExpirySettings,
|
||||
AgentOptions: agentOptions,
|
||||
SMTPSettings: smtpSettings,
|
||||
SSOSettings: ssoSettings,
|
||||
AgentOptions: agentOptions,
|
||||
|
||||
FleetDesktop: fleetDesktop,
|
||||
|
||||
@@ -208,9 +206,7 @@ func modifyAppConfigEndpoint(ctx context.Context, request interface{}, svc fleet
|
||||
},
|
||||
}
|
||||
|
||||
if response.SMTPSettings.SMTPPassword != "" {
|
||||
response.SMTPSettings.SMTPPassword = fleet.MaskedPassword
|
||||
}
|
||||
response.Obfuscate()
|
||||
|
||||
if (!license.IsPremium()) || response.FleetDesktop.TransparencyURL == "" {
|
||||
response.FleetDesktop.TransparencyURL = fleet.DefaultTransparencyURL
|
||||
@@ -235,7 +231,16 @@ func (svc *Service) ModifyAppConfig(ctx context.Context, p []byte, applyOpts fle
|
||||
// We do not use svc.License(ctx) to allow roles (like GitOps) write but not read access to AppConfig.
|
||||
license, _ := license.FromContext(ctx)
|
||||
|
||||
oldSmtpSettings := appConfig.SMTPSettings
|
||||
var oldSMTPSettings fleet.SMTPSettings
|
||||
if appConfig.SMTPSettings != nil {
|
||||
oldSMTPSettings = *appConfig.SMTPSettings
|
||||
} else {
|
||||
// SMTPSettings used to be a non-pointer on previous iterations,
|
||||
// so if current SMTPSettings are not present (with empty values),
|
||||
// then this is a bug, let's log an error.
|
||||
level.Error(svc.logger).Log("smtp_settings are not present")
|
||||
}
|
||||
|
||||
oldAgentOptions := ""
|
||||
if appConfig.AgentOptions != nil {
|
||||
oldAgentOptions = string(*appConfig.AgentOptions)
|
||||
@@ -272,9 +277,11 @@ func (svc *Service) ModifyAppConfig(ctx context.Context, p []byte, applyOpts fle
|
||||
}
|
||||
}
|
||||
|
||||
validateSSOSettings(newAppConfig, appConfig, invalid, license)
|
||||
if invalid.HasErrors() {
|
||||
return nil, ctxerr.Wrap(ctx, invalid)
|
||||
if newAppConfig.SSOSettings != nil {
|
||||
validateSSOSettings(newAppConfig, appConfig, invalid, license)
|
||||
if invalid.HasErrors() {
|
||||
return nil, ctxerr.Wrap(ctx, invalid)
|
||||
}
|
||||
}
|
||||
|
||||
// We apply the config that is incoming to the old one
|
||||
@@ -346,20 +353,23 @@ func (svc *Service) ModifyAppConfig(ctx context.Context, p []byte, applyOpts fle
|
||||
return svc.AppConfigObfuscated(ctx)
|
||||
}
|
||||
|
||||
// ignore the values for SMTPEnabled and SMTPConfigured
|
||||
oldSmtpSettings.SMTPEnabled = appConfig.SMTPSettings.SMTPEnabled
|
||||
oldSmtpSettings.SMTPConfigured = appConfig.SMTPSettings.SMTPConfigured
|
||||
// Perform validation of the applied SMTP settings.
|
||||
if newAppConfig.SMTPSettings != nil {
|
||||
// Ignore the values for SMTPEnabled and SMTPConfigured.
|
||||
oldSMTPSettings.SMTPEnabled = appConfig.SMTPSettings.SMTPEnabled
|
||||
oldSMTPSettings.SMTPConfigured = appConfig.SMTPSettings.SMTPConfigured
|
||||
|
||||
// if we enable SMTP and the settings have changed, then we send a test email
|
||||
if appConfig.SMTPSettings.SMTPEnabled {
|
||||
if oldSmtpSettings != appConfig.SMTPSettings || !appConfig.SMTPSettings.SMTPConfigured {
|
||||
if err = svc.sendTestEmail(ctx, appConfig); err != nil {
|
||||
return nil, ctxerr.Wrap(ctx, err)
|
||||
// If we enable SMTP and the settings have changed, then we send a test email.
|
||||
if appConfig.SMTPSettings.SMTPEnabled {
|
||||
if oldSMTPSettings != *appConfig.SMTPSettings || !appConfig.SMTPSettings.SMTPConfigured {
|
||||
if err = svc.sendTestEmail(ctx, appConfig); err != nil {
|
||||
return nil, ctxerr.Wrap(ctx, err)
|
||||
}
|
||||
}
|
||||
appConfig.SMTPSettings.SMTPConfigured = true
|
||||
} else {
|
||||
appConfig.SMTPSettings.SMTPConfigured = false
|
||||
}
|
||||
appConfig.SMTPSettings.SMTPConfigured = true
|
||||
} else {
|
||||
appConfig.SMTPSettings.SMTPConfigured = false
|
||||
}
|
||||
|
||||
delJira, err := fleet.ValidateJiraIntegrations(ctx, storedJiraByProjectKey, newAppConfig.Integrations.Jira)
|
||||
@@ -648,9 +658,13 @@ func validateSSOProviderSettings(incoming, existing fleet.SSOProviderSettings, i
|
||||
}
|
||||
|
||||
func validateSSOSettings(p fleet.AppConfig, existing *fleet.AppConfig, invalid *fleet.InvalidArgumentError, license *fleet.LicenseInfo) {
|
||||
if p.SSOSettings.EnableSSO {
|
||||
if p.SSOSettings != nil && p.SSOSettings.EnableSSO {
|
||||
|
||||
validateSSOProviderSettings(p.SSOSettings.SSOProviderSettings, existing.SSOSettings.SSOProviderSettings, invalid)
|
||||
var existingSSOProviderSettings fleet.SSOProviderSettings
|
||||
if existing.SSOSettings != nil {
|
||||
existingSSOProviderSettings = existing.SSOSettings.SSOProviderSettings
|
||||
}
|
||||
validateSSOProviderSettings(p.SSOSettings.SSOProviderSettings, existingSSOProviderSettings, invalid)
|
||||
|
||||
if !license.IsPremium() {
|
||||
if p.SSOSettings.EnableJITProvisioning {
|
||||
|
||||
@@ -349,7 +349,7 @@ func TestSSONotPresent(t *testing.T) {
|
||||
func TestNeedFieldsPresent(t *testing.T) {
|
||||
invalid := &fleet.InvalidArgumentError{}
|
||||
config := fleet.AppConfig{
|
||||
SSOSettings: fleet.SSOSettings{
|
||||
SSOSettings: &fleet.SSOSettings{
|
||||
EnableSSO: true,
|
||||
SSOProviderSettings: fleet.SSOProviderSettings{
|
||||
EntityID: "fleet",
|
||||
@@ -366,7 +366,7 @@ func TestNeedFieldsPresent(t *testing.T) {
|
||||
func TestShortIDPName(t *testing.T) {
|
||||
invalid := &fleet.InvalidArgumentError{}
|
||||
config := fleet.AppConfig{
|
||||
SSOSettings: fleet.SSOSettings{
|
||||
SSOSettings: &fleet.SSOSettings{
|
||||
EnableSSO: true,
|
||||
SSOProviderSettings: fleet.SSOProviderSettings{
|
||||
EntityID: "fleet",
|
||||
@@ -384,7 +384,7 @@ func TestShortIDPName(t *testing.T) {
|
||||
func TestMissingMetadata(t *testing.T) {
|
||||
invalid := &fleet.InvalidArgumentError{}
|
||||
config := fleet.AppConfig{
|
||||
SSOSettings: fleet.SSOSettings{
|
||||
SSOSettings: &fleet.SSOSettings{
|
||||
EnableSSO: true,
|
||||
SSOProviderSettings: fleet.SSOProviderSettings{
|
||||
EntityID: "fleet",
|
||||
@@ -401,7 +401,7 @@ func TestMissingMetadata(t *testing.T) {
|
||||
|
||||
func TestJITProvisioning(t *testing.T) {
|
||||
config := fleet.AppConfig{
|
||||
SSOSettings: fleet.SSOSettings{
|
||||
SSOSettings: &fleet.SSOSettings{
|
||||
EnableSSO: true,
|
||||
EnableJITProvisioning: true,
|
||||
SSOProviderSettings: fleet.SSOProviderSettings{
|
||||
@@ -429,9 +429,11 @@ func TestJITProvisioning(t *testing.T) {
|
||||
|
||||
t.Run("doesn't care if JIT provisioning is set to false on free licenses", func(t *testing.T) {
|
||||
invalid := &fleet.InvalidArgumentError{}
|
||||
oldConfig := &fleet.AppConfig{}
|
||||
|
||||
oldConfig.SSOSettings.EnableJITProvisioning = true
|
||||
oldConfig := &fleet.AppConfig{
|
||||
SSOSettings: &fleet.SSOSettings{
|
||||
EnableJITProvisioning: false,
|
||||
},
|
||||
}
|
||||
config.SSOSettings.EnableJITProvisioning = false
|
||||
validateSSOSettings(config, oldConfig, invalid, &fleet.LicenseInfo{})
|
||||
require.False(t, invalid.HasErrors())
|
||||
@@ -449,7 +451,9 @@ func TestAppConfigSecretsObfuscated(t *testing.T) {
|
||||
|
||||
ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
|
||||
return &fleet.AppConfig{
|
||||
SMTPSettings: fleet.SMTPSettings{SMTPPassword: "smtppassword"},
|
||||
SMTPSettings: &fleet.SMTPSettings{
|
||||
SMTPPassword: "smtppassword",
|
||||
},
|
||||
Integrations: fleet.Integrations{
|
||||
Jira: []*fleet.JiraIntegration{
|
||||
{APIToken: "jiratoken"},
|
||||
@@ -553,7 +557,7 @@ func TestModifyAppConfigSMTPConfigured(t *testing.T) {
|
||||
ServerSettings: fleet.ServerSettings{
|
||||
ServerURL: "https://example.org",
|
||||
},
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPSettings: &fleet.SMTPSettings{
|
||||
SMTPEnabled: true,
|
||||
SMTPConfigured: true,
|
||||
},
|
||||
@@ -569,7 +573,7 @@ func TestModifyAppConfigSMTPConfigured(t *testing.T) {
|
||||
|
||||
// Disable SMTP.
|
||||
newAppConfig := fleet.AppConfig{
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPSettings: &fleet.SMTPSettings{
|
||||
SMTPEnabled: false,
|
||||
SMTPConfigured: true,
|
||||
},
|
||||
@@ -967,3 +971,127 @@ func TestMDMAppleConfig(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestModifyAppConfigSMTPSSOAgentOptions(t *testing.T) {
|
||||
ds := new(mock.Store)
|
||||
svc, ctx := newTestService(t, ds, nil, nil)
|
||||
|
||||
// SMTP and SSO are initially set.
|
||||
agentOptions := json.RawMessage(`
|
||||
{
|
||||
"config": {
|
||||
"options": {
|
||||
"distributed_interval": 10
|
||||
}
|
||||
},
|
||||
"overrides": {
|
||||
"platforms": {
|
||||
"darwin": {
|
||||
"options": {
|
||||
"distributed_interval": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
dsAppConfig := &fleet.AppConfig{
|
||||
OrgInfo: fleet.OrgInfo{
|
||||
OrgName: "Test",
|
||||
},
|
||||
ServerSettings: fleet.ServerSettings{
|
||||
ServerURL: "https://example.org",
|
||||
},
|
||||
SMTPSettings: &fleet.SMTPSettings{
|
||||
SMTPEnabled: true,
|
||||
SMTPConfigured: true,
|
||||
SMTPSenderAddress: "foobar@example.com",
|
||||
},
|
||||
SSOSettings: &fleet.SSOSettings{
|
||||
EnableSSO: true,
|
||||
SSOProviderSettings: fleet.SSOProviderSettings{
|
||||
MetadataURL: "foobar.example.com/metadata",
|
||||
},
|
||||
},
|
||||
AgentOptions: &agentOptions,
|
||||
}
|
||||
|
||||
ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
|
||||
return dsAppConfig, nil
|
||||
}
|
||||
ds.SaveAppConfigFunc = func(ctx context.Context, conf *fleet.AppConfig) error {
|
||||
*dsAppConfig = *conf
|
||||
return nil
|
||||
}
|
||||
ds.NewActivityFunc = func(ctx context.Context, user *fleet.User, activity fleet.ActivityDetails) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Not sending smtp_settings, sso_settings or agent_settings will do nothing.
|
||||
b := []byte(`{}`)
|
||||
admin := &fleet.User{GlobalRole: ptr.String(fleet.RoleAdmin)}
|
||||
ctx = viewer.NewContext(ctx, viewer.Viewer{User: admin})
|
||||
updatedAppConfig, err := svc.ModifyAppConfig(ctx, b, fleet.ApplySpecOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.True(t, updatedAppConfig.SMTPSettings.SMTPEnabled)
|
||||
require.True(t, dsAppConfig.SMTPSettings.SMTPEnabled)
|
||||
require.True(t, updatedAppConfig.SSOSettings.EnableSSO)
|
||||
require.True(t, dsAppConfig.SSOSettings.EnableSSO)
|
||||
require.Equal(t, agentOptions, *updatedAppConfig.AgentOptions)
|
||||
require.Equal(t, agentOptions, *dsAppConfig.AgentOptions)
|
||||
|
||||
// Not sending sso_settings or agent settings will not change them, and
|
||||
// sending SMTP settings will change them.
|
||||
b = []byte(`{"smtp_settings": {"enable_smtp": false}}`)
|
||||
updatedAppConfig, err = svc.ModifyAppConfig(ctx, b, fleet.ApplySpecOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.False(t, updatedAppConfig.SMTPSettings.SMTPEnabled)
|
||||
require.False(t, dsAppConfig.SMTPSettings.SMTPEnabled)
|
||||
require.True(t, updatedAppConfig.SSOSettings.EnableSSO)
|
||||
require.True(t, dsAppConfig.SSOSettings.EnableSSO)
|
||||
require.Equal(t, agentOptions, *updatedAppConfig.AgentOptions)
|
||||
require.Equal(t, agentOptions, *dsAppConfig.AgentOptions)
|
||||
|
||||
// Not sending smtp_settings or agent settings will not change them, and
|
||||
// sending SSO settings will change them.
|
||||
b = []byte(`{"sso_settings": {"enable_sso": false}}`)
|
||||
updatedAppConfig, err = svc.ModifyAppConfig(ctx, b, fleet.ApplySpecOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.False(t, updatedAppConfig.SMTPSettings.SMTPEnabled)
|
||||
require.False(t, dsAppConfig.SMTPSettings.SMTPEnabled)
|
||||
require.False(t, updatedAppConfig.SSOSettings.EnableSSO)
|
||||
require.False(t, dsAppConfig.SSOSettings.EnableSSO)
|
||||
require.Equal(t, agentOptions, *updatedAppConfig.AgentOptions)
|
||||
require.Equal(t, agentOptions, *dsAppConfig.AgentOptions)
|
||||
|
||||
// Not sending smtp_settings or sso_settings will not change them, and
|
||||
// sending agent options will change them.
|
||||
newAgentOptions := json.RawMessage(`{
|
||||
"config": {
|
||||
"options": {
|
||||
"distributed_interval": 100
|
||||
}
|
||||
},
|
||||
"overrides": {
|
||||
"platforms": {
|
||||
"darwin": {
|
||||
"options": {
|
||||
"distributed_interval": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
b = []byte(`{"agent_options": ` + string(newAgentOptions) + `}`)
|
||||
updatedAppConfig, err = svc.ModifyAppConfig(ctx, b, fleet.ApplySpecOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.False(t, updatedAppConfig.SMTPSettings.SMTPEnabled)
|
||||
require.False(t, dsAppConfig.SMTPSettings.SMTPEnabled)
|
||||
require.False(t, updatedAppConfig.SSOSettings.EnableSSO)
|
||||
require.False(t, dsAppConfig.SSOSettings.EnableSSO)
|
||||
require.Equal(t, newAgentOptions, *dsAppConfig.AgentOptions)
|
||||
require.Equal(t, newAgentOptions, *dsAppConfig.AgentOptions)
|
||||
}
|
||||
|
||||
@@ -104,10 +104,15 @@ func (svc *Service) InviteNewUser(ctx context.Context, payload fleet.InvitePaylo
|
||||
if invitedBy == "" {
|
||||
invitedBy = inviter.Email
|
||||
}
|
||||
var smtpSettings fleet.SMTPSettings
|
||||
if config.SMTPSettings != nil {
|
||||
smtpSettings = *config.SMTPSettings
|
||||
}
|
||||
inviteEmail := fleet.Email{
|
||||
Subject: "You are Invited to Fleet",
|
||||
To: []string{invite.Email},
|
||||
Config: config,
|
||||
Subject: "You are Invited to Fleet",
|
||||
To: []string{invite.Email},
|
||||
ServerURL: config.ServerSettings.ServerURL,
|
||||
SMTPSettings: smtpSettings,
|
||||
Mailer: &mail.InviteMailer{
|
||||
Invite: invite,
|
||||
BaseURL: template.URL(config.ServerSettings.ServerURL + svc.config.Server.URLPrefix),
|
||||
|
||||
@@ -52,7 +52,7 @@ func TestMailService(t *testing.T) {
|
||||
|
||||
ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
|
||||
return &fleet.AppConfig{
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPSettings: &fleet.SMTPSettings{
|
||||
SMTPEnabled: true,
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameUserNamePassword,
|
||||
|
||||
@@ -69,6 +69,11 @@ func (svc *Service) sendTestEmail(ctx context.Context, config *fleet.AppConfig)
|
||||
return fleet.ErrNoContext
|
||||
}
|
||||
|
||||
var smtpSettings fleet.SMTPSettings
|
||||
if config.SMTPSettings != nil {
|
||||
smtpSettings = *config.SMTPSettings
|
||||
}
|
||||
|
||||
testMail := fleet.Email{
|
||||
Subject: "Hello from Fleet",
|
||||
To: []string{vc.User.Email},
|
||||
@@ -76,7 +81,8 @@ func (svc *Service) sendTestEmail(ctx context.Context, config *fleet.AppConfig)
|
||||
BaseURL: template.URL(config.ServerSettings.ServerURL + svc.config.Server.URLPrefix),
|
||||
AssetURL: getAssetURL(),
|
||||
},
|
||||
Config: config,
|
||||
SMTPSettings: smtpSettings,
|
||||
ServerURL: config.ServerSettings.ServerURL,
|
||||
}
|
||||
|
||||
if err := mail.Test(svc.mailService, testMail); err != nil {
|
||||
|
||||
@@ -294,7 +294,7 @@ func (svc *Service) InitiateSSO(ctx context.Context, redirectURL string) (string
|
||||
return "", ctxerr.Wrap(ctx, err, "InitiateSSO getting app config")
|
||||
}
|
||||
|
||||
if !appConfig.SSOSettings.EnableSSO {
|
||||
if appConfig.SSOSettings == nil || !appConfig.SSOSettings.EnableSSO {
|
||||
err := &fleet.BadRequestError{Message: "organization not configured to use sso"}
|
||||
return "", ctxerr.Wrap(ctx, newSSOError(err, ssoOrgDisabled), "initiate sso")
|
||||
}
|
||||
@@ -448,7 +448,7 @@ func (svc *Service) InitSSOCallback(ctx context.Context, auth fleet.Auth) (strin
|
||||
return "", ctxerr.Wrap(ctx, err, "get config for sso")
|
||||
}
|
||||
|
||||
if !appConfig.SSOSettings.EnableSSO {
|
||||
if appConfig.SSOSettings == nil || !appConfig.SSOSettings.EnableSSO {
|
||||
err := ctxerr.New(ctx, "organization not configured to use sso")
|
||||
return "", ctxerr.Wrap(ctx, newSSOError(err, ssoOrgDisabled), "callback sso")
|
||||
}
|
||||
@@ -563,10 +563,15 @@ func (svc *Service) SSOSettings(ctx context.Context) (*fleet.SessionSSOSettings,
|
||||
return nil, ctxerr.Wrap(ctx, err, "SessionSSOSettings getting app config")
|
||||
}
|
||||
|
||||
var ssoSettings fleet.SSOSettings
|
||||
if appConfig.SSOSettings != nil {
|
||||
ssoSettings = *appConfig.SSOSettings
|
||||
}
|
||||
|
||||
settings := &fleet.SessionSSOSettings{
|
||||
IDPName: appConfig.SSOSettings.IDPName,
|
||||
IDPImageURL: appConfig.SSOSettings.IDPImageURL,
|
||||
SSOEnabled: appConfig.SSOSettings.EnableSSO,
|
||||
IDPName: ssoSettings.IDPName,
|
||||
IDPImageURL: ssoSettings.IDPImageURL,
|
||||
SSOEnabled: ssoSettings.EnableSSO,
|
||||
}
|
||||
return settings, nil
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ func TestGetSSOUser(t *testing.T) {
|
||||
|
||||
ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
|
||||
return &fleet.AppConfig{
|
||||
SSOSettings: fleet.SSOSettings{
|
||||
SSOSettings: &fleet.SSOSettings{
|
||||
EnableSSO: true,
|
||||
EnableSSOIdPLogin: true,
|
||||
EnableJITProvisioning: true,
|
||||
@@ -321,7 +321,7 @@ func TestGetSSOUser(t *testing.T) {
|
||||
|
||||
ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
|
||||
return &fleet.AppConfig{
|
||||
SSOSettings: fleet.SSOSettings{
|
||||
SSOSettings: &fleet.SSOSettings{
|
||||
EnableSSO: true,
|
||||
EnableSSOIdPLogin: true,
|
||||
EnableJITProvisioning: false,
|
||||
@@ -347,7 +347,7 @@ func TestGetSSOUser(t *testing.T) {
|
||||
|
||||
ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
|
||||
return &fleet.AppConfig{
|
||||
SSOSettings: fleet.SSOSettings{
|
||||
SSOSettings: &fleet.SSOSettings{
|
||||
EnableSSO: true,
|
||||
EnableSSOIdPLogin: true,
|
||||
EnableJITProvisioning: true,
|
||||
|
||||
+20
-7
@@ -5,11 +5,12 @@ import (
|
||||
"database/sql"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"github.com/go-kit/kit/log/level"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/kit/log/level"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/server"
|
||||
"github.com/fleetdm/fleet/v4/server/authz"
|
||||
authz_ctx "github.com/fleetdm/fleet/v4/server/contexts/authz"
|
||||
@@ -777,10 +778,16 @@ func (svc *Service) modifyEmailAddress(ctx context.Context, user *fleet.User, em
|
||||
return err
|
||||
}
|
||||
|
||||
var smtpSettings fleet.SMTPSettings
|
||||
if config.SMTPSettings != nil {
|
||||
smtpSettings = *config.SMTPSettings
|
||||
}
|
||||
|
||||
changeEmail := fleet.Email{
|
||||
Subject: "Confirm Fleet Email Change",
|
||||
To: []string{email},
|
||||
Config: config,
|
||||
Subject: "Confirm Fleet Email Change",
|
||||
To: []string{email},
|
||||
SMTPSettings: smtpSettings,
|
||||
ServerURL: config.ServerSettings.ServerURL,
|
||||
Mailer: &mail.ChangeEmailMailer{
|
||||
Token: token,
|
||||
BaseURL: template.URL(config.ServerSettings.ServerURL + svc.config.Server.URLPrefix),
|
||||
@@ -1021,10 +1028,16 @@ func (svc *Service) RequestPasswordReset(ctx context.Context, email string) erro
|
||||
return err
|
||||
}
|
||||
|
||||
var smtpSettings fleet.SMTPSettings
|
||||
if config.SMTPSettings != nil {
|
||||
smtpSettings = *config.SMTPSettings
|
||||
}
|
||||
|
||||
resetEmail := fleet.Email{
|
||||
Subject: "Reset Your Fleet Password",
|
||||
To: []string{user.Email},
|
||||
Config: config,
|
||||
Subject: "Reset Your Fleet Password",
|
||||
To: []string{user.Email},
|
||||
SMTPSettings: smtpSettings,
|
||||
ServerURL: config.ServerSettings.ServerURL,
|
||||
Mailer: &mail.PasswordResetMailer{
|
||||
BaseURL: template.URL(config.ServerSettings.ServerURL + svc.config.Server.URLPrefix),
|
||||
AssetURL: getAssetURL(),
|
||||
|
||||
@@ -443,7 +443,7 @@ func TestModifyUserEmail(t *testing.T) {
|
||||
}
|
||||
ms.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
|
||||
config := &fleet.AppConfig{
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPSettings: &fleet.SMTPSettings{
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameNone,
|
||||
SMTPPort: 1025,
|
||||
@@ -492,7 +492,7 @@ func TestModifyUserEmailNoPassword(t *testing.T) {
|
||||
}
|
||||
ms.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
|
||||
config := &fleet.AppConfig{
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPSettings: &fleet.SMTPSettings{
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameNone,
|
||||
SMTPPort: 1025,
|
||||
@@ -540,7 +540,7 @@ func TestModifyAdminUserEmailNoPassword(t *testing.T) {
|
||||
}
|
||||
ms.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
|
||||
config := &fleet.AppConfig{
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPSettings: &fleet.SMTPSettings{
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameNone,
|
||||
SMTPPort: 1025,
|
||||
@@ -592,7 +592,7 @@ func TestModifyAdminUserEmailPassword(t *testing.T) {
|
||||
}
|
||||
ms.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
|
||||
config := &fleet.AppConfig{
|
||||
SMTPSettings: fleet.SMTPSettings{
|
||||
SMTPSettings: &fleet.SMTPSettings{
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameNone,
|
||||
SMTPPort: 1025,
|
||||
|
||||
Reference in New Issue
Block a user