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:
Lucas Manuel Rodriguez
2023-06-07 16:06:36 -03:00
committed by GitHub
parent 0271ff79cf
commit 2a532ede94
23 changed files with 506 additions and 194 deletions
@@ -0,0 +1 @@
* `GET /api/_version_/fleet/config` to omit fields `smtp_settings` and `sso_settings` if not set.
+1 -1
View File
@@ -554,7 +554,7 @@ the way that the Fleet server works.
}
// setup mail service
if appCfg.SMTPSettings.SMTPEnabled {
if appCfg.SMTPSettings != nil && appCfg.SMTPSettings.SMTPEnabled {
// if SMTP is already enabled then default the backend to empty string, which fill force load the SMTP implementation
if config.Email.EmailBackend != "" {
config.Email.EmailBackend = ""
+2
View File
@@ -1386,6 +1386,8 @@ func TestApplyMacosSetup(t *testing.T) {
OrgInfo: fleet.OrgInfo{OrgName: "Fleet"},
ServerSettings: fleet.ServerSettings{ServerURL: "https://example.org"},
MDM: fleet.MDM{EnabledAndConfigured: true},
SMTPSettings: &fleet.SMTPSettings{},
SSOSettings: &fleet.SSOSettings{},
}
mockStore.Unlock()
ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
+102
View File
@@ -554,6 +554,8 @@ func TestGetConfig(t *testing.T) {
return &fleet.AppConfig{
Features: fleet.Features{EnableHostUsers: true},
VulnerabilitySettings: fleet.VulnerabilitySettings{DatabasesPath: "/some/path"},
SMTPSettings: &fleet.SMTPSettings{},
SSOSettings: &fleet.SSOSettings{},
}, nil
}
@@ -1933,3 +1935,103 @@ func TestUserIsObserver(t *testing.T) {
})
}
}
func TestGetConfigAgentOptionsSSOAndSMTP(t *testing.T) {
_, ds := runServerWithMockedDS(t)
agentOpts := json.RawMessage(`
{
"config": {
"options": {
"distributed_interval": 10
}
},
"overrides": {
"platforms": {
"darwin": {
"options": {
"distributed_interval": 5
}
}
}
}
}`)
ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
return &fleet.AppConfig{
AgentOptions: &agentOpts,
SSOSettings: &fleet.SSOSettings{},
SMTPSettings: &fleet.SMTPSettings{},
}, nil
}
setCurrentUserSession := func(user *fleet.User) {
user, err := ds.NewUser(context.Background(), user)
require.NoError(t, err)
ds.SessionByKeyFunc = func(ctx context.Context, key string) (*fleet.Session, error) {
return &fleet.Session{
CreateTimestamp: fleet.CreateTimestamp{CreatedAt: time.Now()},
ID: 1,
AccessedAt: time.Now(),
UserID: user.ID,
Key: key,
}, nil
}
ds.UserByIDFunc = func(ctx context.Context, id uint) (*fleet.User, error) {
return user, nil
}
}
for _, tc := range []struct {
name string
user *fleet.User
checkOutput func(output string) bool
}{
{
name: "global admin",
user: &fleet.User{
ID: 1,
Name: "Global admin",
Password: []byte("p4ssw0rd.123"),
Email: "ga@example.com",
GlobalRole: ptr.String(fleet.RoleAdmin),
},
checkOutput: func(output string) bool {
return strings.Contains(output, "sso_settings") && strings.Contains(output, "smtp_settings")
},
},
{
name: "global observer",
user: &fleet.User{
ID: 2,
Name: "Global observer",
Password: []byte("p4ssw0rd.123"),
Email: "go@example.com",
GlobalRole: ptr.String(fleet.RoleObserverPlus),
},
checkOutput: func(output string) bool {
return !strings.Contains(output, "sso_settings") && !strings.Contains(output, "smtp_settings")
},
},
{
name: "team observer",
user: &fleet.User{
ID: 3,
Name: "Team observer",
Password: []byte("p4ssw0rd.123"),
Email: "tm@example.com",
GlobalRole: nil,
Teams: []fleet.UserTeam{{Role: fleet.RoleObserver}},
},
checkOutput: func(output string) bool {
return !strings.Contains(output, "sso_settings") && !strings.Contains(output, "smtp_settings")
},
},
} {
t.Run(tc.name, func(t *testing.T) {
setCurrentUserSession(tc.user)
ok := tc.checkOutput(runAppForTest(t, []string{"get", "config"}))
require.True(t, ok)
})
}
}
+5 -1
View File
@@ -63,7 +63,10 @@ GitOps is an API-only and write-only role that can be used on CI/CD pipelines.
| Create, edit, and delete teams\* | | | | ✅ | ✅ |
| Create, edit, and delete [enroll secrets](https://fleetdm.com/docs/deploying/faq#when-do-i-need-to-deploy-a-new-enroll-secret-to-my-hosts) | | | ✅ | ✅ | ✅ |
| Create, edit, and delete [enroll secrets for teams](https://fleetdm.com/docs/using-fleet/rest-api#get-enroll-secrets-for-a-team)\* | | | ✅ | ✅ | |
| Read organization settings and agent options\*** | ✅ | ✅ | ✅ | ✅ | |
| Read organization settings\*** | ✅ | ✅ | ✅ | ✅ | |
| Read Single Sign-On settings\*** | | | | ✅ | |
| Read SMTP settings\*** | | | | ✅ | |
| Read osquery agent options\*** | | | | ✅ | |
| Edit [organization settings](https://fleetdm.com/docs/using-fleet/configuration-files#organization-settings) | | | | ✅ | ✅ |
| Edit [agent options](https://fleetdm.com/docs/using-fleet/configuration-files#agent-options) | | | | ✅ | ✅ |
| Edit [agent options for hosts assigned to teams](https://fleetdm.com/docs/using-fleet/configuration-files#team-agent-options)\* | | | | ✅ | ✅ |
@@ -131,6 +134,7 @@ Users that are members of multiple teams can be assigned different roles for eac
| Add and remove team members | | | | ✅ | ✅ |
| Edit team name | | | | ✅ | ✅ |
| Create, edit, and delete [team enroll secrets](https://fleetdm.com/docs/using-fleet/rest-api#get-enroll-secrets-for-a-team) | | | ✅ | ✅ | |
| Read organization settings\* | ✅ | ✅ | ✅ | ✅ | |
| Read agent options\* | ✅ | ✅ | ✅ | ✅ | |
| Edit [agent options](https://fleetdm.com/docs/using-fleet/configuration-files#agent-options) | | | | ✅ | ✅ |
| Initiate [file carving](https://fleetdm.com/docs/using-fleet/rest-api#file-carving) | | | ✅ | ✅ | |
+6 -1
View File
@@ -646,10 +646,15 @@ func (svc *Service) InitiateMDMAppleSSOCallback(ctx context.Context, auth fleet.
return "", ctxerr.Wrap(ctx, err, "validate request in session")
}
var ssoSettings fleet.SSOSettings
if appConfig.SSOSettings != nil {
ssoSettings = *appConfig.SSOSettings
}
err = sso.ValidateAudiences(
*metadata,
auth,
appConfig.SSOSettings.EntityID,
ssoSettings.EntityID,
appConfig.ServerSettings.ServerURL,
appConfig.ServerSettings.ServerURL+svc.config.Server.URLPrefix+"/api/v1/fleet/mdm/sso/callback",
)
+2 -2
View File
@@ -34,7 +34,7 @@ func (svc *Service) GetSSOUser(ctx context.Context, auth fleet.Auth) (*fleet.Use
// If JIT provisioning is disabled, then Fleet does not attempt to change
// the role of the existing user.
if !config.SSOSettings.EnableJITProvisioning {
if config.SSOSettings == nil || !config.SSOSettings.EnableJITProvisioning {
return user, nil
}
@@ -75,7 +75,7 @@ func (svc *Service) GetSSOUser(ctx context.Context, auth fleet.Auth) (*fleet.Use
}
return user, nil
case errors.As(err, &nfe):
if !config.SSOSettings.EnableJITProvisioning {
if config.SSOSettings == nil || !config.SSOSettings.EnableJITProvisioning {
return nil, err
}
default:
+1 -1
View File
@@ -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
View File
@@ -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()
+5 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 {
+138 -10
View File
@@ -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)
}
+8 -3
View File
@@ -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),
+1 -1
View File
@@ -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,
+7 -1
View File
@@ -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 {
+10 -5
View File
@@ -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
}
+3 -3
View File
@@ -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
View File
@@ -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(),
+4 -4
View File
@@ -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,