diff --git a/app/enterprise.go b/app/enterprise.go index 745294d26e..0578c9408e 100644 --- a/app/enterprise.go +++ b/app/enterprise.go @@ -107,6 +107,12 @@ func RegisterSamlInterface(f func(*App) einterfaces.SamlInterface) { samlInterface = f } +var samlInterfaceNew func(*App) einterfaces.SamlInterface + +func RegisterNewSamlInterface(f func(*App) einterfaces.SamlInterface) { + samlInterfaceNew = f +} + var notificationInterface func(*App) einterfaces.NotificationInterface func RegisterNotificationInterface(f func(*App) einterfaces.NotificationInterface) { @@ -136,7 +142,13 @@ func (s *Server) initEnterprise() { s.Notification = notificationInterface(s.FakeApp()) } if samlInterface != nil { - s.Saml = samlInterface(s.FakeApp()) + if *s.FakeApp().Config().ExperimentalSettings.UseNewSAMLLibrary && samlInterfaceNew != nil { + mlog.Debug("Loading new SAML2 library") + s.Saml = samlInterfaceNew(s.FakeApp()) + } else { + mlog.Debug("Loading original SAML library") + s.Saml = samlInterface(s.FakeApp()) + } s.AddConfigListener(func(_, cfg *model.Config) { if err := s.Saml.ConfigureSP(); err != nil { mlog.Error("An error occurred while configuring SAML Service Provider", mlog.Err(err)) diff --git a/app/enterprise_test.go b/app/enterprise_test.go new file mode 100644 index 0000000000..d5a05cf6fb --- /dev/null +++ b/app/enterprise_test.go @@ -0,0 +1,116 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package app + +import ( + "testing" + + "github.com/mattermost/mattermost-server/v5/einterfaces" + "github.com/mattermost/mattermost-server/v5/einterfaces/mocks" + "github.com/mattermost/mattermost-server/v5/model" + "github.com/stretchr/testify/assert" +) + +func TestSAMLSettings(t *testing.T) { + tt := []struct { + name string + setSAMLInterface bool + setNewInterface bool + useNewSAMLLibrary bool + isNil bool + metadata string + }{ + { + name: "No SAML Interfaces, default setting", + setSAMLInterface: false, + setNewInterface: false, + useNewSAMLLibrary: false, + isNil: true, + }, + { + name: "No SAML Interfaces, set config true", + setSAMLInterface: false, + setNewInterface: false, + useNewSAMLLibrary: true, + isNil: true, + }, + { + name: "Orignal SAML Interface, default setting", + setSAMLInterface: true, + setNewInterface: false, + useNewSAMLLibrary: false, + isNil: false, + metadata: "samlOne", + }, + { + name: "Orignal SAML Interface, config true", + setSAMLInterface: true, + setNewInterface: false, + useNewSAMLLibrary: true, + isNil: false, + metadata: "samlOne", + }, + { + name: "Both SAML Interfaces, default setting", + setSAMLInterface: true, + setNewInterface: true, + useNewSAMLLibrary: false, + isNil: false, + metadata: "samlOne", + }, + { + name: "Both SAML Interfaces, config true", + setSAMLInterface: true, + setNewInterface: true, + useNewSAMLLibrary: true, + isNil: false, + metadata: "samlTwo", + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + saml := &mocks.SamlInterface{} + saml.Mock.On("ConfigureSP").Return(nil) + saml.Mock.On("GetMetadata").Return("samlOne", nil) + if tc.setSAMLInterface { + RegisterSamlInterface(func(a *App) einterfaces.SamlInterface { + return saml + }) + } else { + RegisterSamlInterface(nil) + } + + saml2 := &mocks.SamlInterface{} + saml2.Mock.On("ConfigureSP").Return(nil) + saml2.Mock.On("GetMetadata").Return("samlTwo", nil) + if tc.setNewInterface { + RegisterNewSamlInterface(func(a *App) einterfaces.SamlInterface { + return saml2 + }) + } else { + RegisterNewSamlInterface(nil) + } + + th := SetupEnterprise(t).InitBasic() + defer th.TearDown() + + if tc.useNewSAMLLibrary { + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.ExperimentalSettings.UseNewSAMLLibrary = tc.useNewSAMLLibrary + }) + } + + th.Server.initEnterprise() + if tc.isNil { + assert.Nil(t, th.App.Srv.Saml) + } else { + assert.NotNil(t, th.App.Srv.Saml) + metadata, err := th.App.Srv.Saml.GetMetadata() + assert.Nil(t, err) + assert.Equal(t, tc.metadata, metadata) + } + }) + } +} diff --git a/model/config.go b/model/config.go index fd9e0e0607..8597b98417 100644 --- a/model/config.go +++ b/model/config.go @@ -797,6 +797,7 @@ type ExperimentalSettings struct { EnableClickToReply *bool `restricted:"true"` LinkMetadataTimeoutMilliseconds *int64 `restricted:"true"` RestrictSystemAdmin *bool `restricted:"true"` + UseNewSAMLLibrary *bool } func (s *ExperimentalSettings) SetDefaults() { @@ -819,6 +820,9 @@ func (s *ExperimentalSettings) SetDefaults() { if s.RestrictSystemAdmin == nil { s.RestrictSystemAdmin = NewBool(false) } + if s.UseNewSAMLLibrary == nil { + s.UseNewSAMLLibrary = NewBool(false) + } } type AnalyticsSettings struct {