MM-27688-OpenId Connect (#16222)
* implement openid connect * update error strings * handle OpenIdSetting.Secret as FAKE SETTING * add openid to telemetry * update config defaults, add telemetry * fix bug with Office365 * Retrieve Office365 AuthData from IdToken * fix linter * add feature flag, reset defaults for config * fix build error * fix unit tests * add authentication permission to Feature Flags * turn off feature flag * set default button color * set default button color only on openid * fix for merging FeatureFlags in config * remove feature flag * revert config changes * remove debug statements Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
2a71fc5ee2
Коммит
f548ecbee1
@@ -31,6 +31,7 @@ type AccessResponse struct {
|
||||
ExpiresIn int32 `json:"expires_in"`
|
||||
Scope string `json:"scope"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
IdToken string `json:"id_token"`
|
||||
}
|
||||
|
||||
// IsValid validates the AccessData and returns an error if it isn't configured
|
||||
|
||||
@@ -45,6 +45,7 @@ const (
|
||||
SERVICE_GITLAB = "gitlab"
|
||||
SERVICE_GOOGLE = "google"
|
||||
SERVICE_OFFICE365 = "office365"
|
||||
SERVICE_OPENID = "openid"
|
||||
|
||||
GENERIC_NO_CHANNEL_NOTIFICATION = "generic_no_channel"
|
||||
GENERIC_NOTIFICATION = "generic"
|
||||
@@ -230,6 +231,7 @@ const (
|
||||
OFFICE365_SETTINGS_DEFAULT_USER_API_ENDPOINT = "https://graph.microsoft.com/v1.0/me"
|
||||
|
||||
CLOUD_SETTINGS_DEFAULT_CWS_URL = "https://customers.mattermost.com"
|
||||
OPENID_SETTINGS_DEFAULT_SCOPE = "profile openid email"
|
||||
|
||||
LOCAL_MODE_SOCKET_PATH = "/var/tmp/mattermost_local.socket"
|
||||
)
|
||||
@@ -960,16 +962,19 @@ func (s *AnalyticsSettings) SetDefaults() {
|
||||
}
|
||||
|
||||
type SSOSettings struct {
|
||||
Enable *bool `access:"authentication"`
|
||||
Secret *string `access:"authentication"`
|
||||
Id *string `access:"authentication"`
|
||||
Scope *string `access:"authentication"`
|
||||
AuthEndpoint *string `access:"authentication"`
|
||||
TokenEndpoint *string `access:"authentication"`
|
||||
UserApiEndpoint *string `access:"authentication"`
|
||||
Enable *bool `access:"authentication"`
|
||||
Secret *string `access:"authentication"`
|
||||
Id *string `access:"authentication"`
|
||||
Scope *string `access:"authentication"`
|
||||
AuthEndpoint *string `access:"authentication"`
|
||||
TokenEndpoint *string `access:"authentication"`
|
||||
UserApiEndpoint *string `access:"authentication"`
|
||||
DiscoveryEndpoint *string `access:"authentication"`
|
||||
ButtonText *string `access:"authentication"`
|
||||
ButtonColor *string `access:"authentication"`
|
||||
}
|
||||
|
||||
func (s *SSOSettings) setDefaults(scope, authEndpoint, tokenEndpoint, userApiEndpoint string) {
|
||||
func (s *SSOSettings) setDefaults(scope, authEndpoint, tokenEndpoint, userApiEndpoint, buttonColor string) {
|
||||
if s.Enable == nil {
|
||||
s.Enable = NewBool(false)
|
||||
}
|
||||
@@ -986,6 +991,10 @@ func (s *SSOSettings) setDefaults(scope, authEndpoint, tokenEndpoint, userApiEnd
|
||||
s.Scope = NewString(scope)
|
||||
}
|
||||
|
||||
if s.DiscoveryEndpoint == nil {
|
||||
s.DiscoveryEndpoint = NewString("")
|
||||
}
|
||||
|
||||
if s.AuthEndpoint == nil {
|
||||
s.AuthEndpoint = NewString(authEndpoint)
|
||||
}
|
||||
@@ -997,17 +1006,26 @@ func (s *SSOSettings) setDefaults(scope, authEndpoint, tokenEndpoint, userApiEnd
|
||||
if s.UserApiEndpoint == nil {
|
||||
s.UserApiEndpoint = NewString(userApiEndpoint)
|
||||
}
|
||||
|
||||
if s.ButtonText == nil {
|
||||
s.ButtonText = NewString("")
|
||||
}
|
||||
|
||||
if s.ButtonColor == nil {
|
||||
s.ButtonColor = NewString(buttonColor)
|
||||
}
|
||||
}
|
||||
|
||||
type Office365Settings struct {
|
||||
Enable *bool `access:"authentication"`
|
||||
Secret *string `access:"authentication"`
|
||||
Id *string `access:"authentication"`
|
||||
Scope *string `access:"authentication"`
|
||||
AuthEndpoint *string `access:"authentication"`
|
||||
TokenEndpoint *string `access:"authentication"`
|
||||
UserApiEndpoint *string `access:"authentication"`
|
||||
DirectoryId *string `access:"authentication"`
|
||||
Enable *bool `access:"authentication"`
|
||||
Secret *string `access:"authentication"`
|
||||
Id *string `access:"authentication"`
|
||||
Scope *string `access:"authentication"`
|
||||
AuthEndpoint *string `access:"authentication"`
|
||||
TokenEndpoint *string `access:"authentication"`
|
||||
UserApiEndpoint *string `access:"authentication"`
|
||||
DiscoveryEndpoint *string `access:"authentication"`
|
||||
DirectoryId *string `access:"authentication"`
|
||||
}
|
||||
|
||||
func (s *Office365Settings) setDefaults() {
|
||||
@@ -1027,6 +1045,10 @@ func (s *Office365Settings) setDefaults() {
|
||||
s.Scope = NewString(OFFICE365_SETTINGS_DEFAULT_SCOPE)
|
||||
}
|
||||
|
||||
if s.DiscoveryEndpoint == nil {
|
||||
s.DiscoveryEndpoint = NewString("")
|
||||
}
|
||||
|
||||
if s.AuthEndpoint == nil {
|
||||
s.AuthEndpoint = NewString(OFFICE365_SETTINGS_DEFAULT_AUTH_ENDPOINT)
|
||||
}
|
||||
@@ -1050,6 +1072,7 @@ func (s *Office365Settings) SSOSettings() *SSOSettings {
|
||||
ssoSettings.Secret = s.Secret
|
||||
ssoSettings.Id = s.Id
|
||||
ssoSettings.Scope = s.Scope
|
||||
ssoSettings.DiscoveryEndpoint = s.DiscoveryEndpoint
|
||||
ssoSettings.AuthEndpoint = s.AuthEndpoint
|
||||
ssoSettings.TokenEndpoint = s.TokenEndpoint
|
||||
ssoSettings.UserApiEndpoint = s.UserApiEndpoint
|
||||
@@ -2948,6 +2971,7 @@ type Config struct {
|
||||
GitLabSettings SSOSettings
|
||||
GoogleSettings SSOSettings
|
||||
Office365Settings Office365Settings
|
||||
OpenIdSettings SSOSettings
|
||||
LdapSettings LdapSettings
|
||||
ComplianceSettings ComplianceSettings
|
||||
LocalizationSettings LocalizationSettings
|
||||
@@ -3004,6 +3028,8 @@ func (o *Config) GetSSOService(service string) *SSOSettings {
|
||||
return &o.GoogleSettings
|
||||
case SERVICE_OFFICE365:
|
||||
return o.Office365Settings.SSOSettings()
|
||||
case SERVICE_OPENID:
|
||||
return &o.OpenIdSettings
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -3039,8 +3065,10 @@ func (o *Config) SetDefaults() {
|
||||
o.EmailSettings.SetDefaults(isUpdate)
|
||||
o.PrivacySettings.setDefaults()
|
||||
o.Office365Settings.setDefaults()
|
||||
o.GitLabSettings.setDefaults("", "", "", "")
|
||||
o.GoogleSettings.setDefaults(GOOGLE_SETTINGS_DEFAULT_SCOPE, GOOGLE_SETTINGS_DEFAULT_AUTH_ENDPOINT, GOOGLE_SETTINGS_DEFAULT_TOKEN_ENDPOINT, GOOGLE_SETTINGS_DEFAULT_USER_API_ENDPOINT)
|
||||
o.Office365Settings.setDefaults()
|
||||
o.GitLabSettings.setDefaults("", "", "", "", "")
|
||||
o.GoogleSettings.setDefaults(GOOGLE_SETTINGS_DEFAULT_SCOPE, GOOGLE_SETTINGS_DEFAULT_AUTH_ENDPOINT, GOOGLE_SETTINGS_DEFAULT_TOKEN_ENDPOINT, GOOGLE_SETTINGS_DEFAULT_USER_API_ENDPOINT, "")
|
||||
o.OpenIdSettings.setDefaults(OPENID_SETTINGS_DEFAULT_SCOPE, "", "", "", "#145DBF")
|
||||
o.ServiceSettings.SetDefaults(isUpdate)
|
||||
o.PasswordSettings.SetDefaults()
|
||||
o.TeamSettings.SetDefaults()
|
||||
@@ -3691,6 +3719,10 @@ func (o *Config) Sanitize() {
|
||||
*o.Office365Settings.Secret = FAKE_SETTING
|
||||
}
|
||||
|
||||
if o.OpenIdSettings.Secret != nil && len(*o.OpenIdSettings.Secret) > 0 {
|
||||
*o.OpenIdSettings.Secret = FAKE_SETTING
|
||||
}
|
||||
|
||||
*o.SqlSettings.DataSource = FAKE_SETTING
|
||||
*o.SqlSettings.AtRestEncryptKey = FAKE_SETTING
|
||||
|
||||
|
||||
@@ -1322,6 +1322,7 @@ func TestConfigSanitize(t *testing.T) {
|
||||
*c.FileSettings.AmazonS3SecretAccessKey = "bar"
|
||||
*c.EmailSettings.SMTPPassword = "baz"
|
||||
*c.GitLabSettings.Secret = "bingo"
|
||||
*c.OpenIdSettings.Secret = "secret"
|
||||
c.SqlSettings.DataSourceReplicas = []string{"stuff"}
|
||||
c.SqlSettings.DataSourceSearchReplicas = []string{"stuff"}
|
||||
|
||||
@@ -1332,6 +1333,7 @@ func TestConfigSanitize(t *testing.T) {
|
||||
assert.Equal(t, FAKE_SETTING, *c.FileSettings.AmazonS3SecretAccessKey)
|
||||
assert.Equal(t, FAKE_SETTING, *c.EmailSettings.SMTPPassword)
|
||||
assert.Equal(t, FAKE_SETTING, *c.GitLabSettings.Secret)
|
||||
assert.Equal(t, FAKE_SETTING, *c.OpenIdSettings.Secret)
|
||||
assert.Equal(t, FAKE_SETTING, *c.SqlSettings.DataSource)
|
||||
assert.Equal(t, FAKE_SETTING, *c.SqlSettings.AtRestEncryptKey)
|
||||
assert.Equal(t, FAKE_SETTING, *c.ElasticsearchSettings.Password)
|
||||
|
||||
@@ -91,7 +91,7 @@ func (glu *GitLabUser) getAuthData() string {
|
||||
return strconv.FormatInt(glu.Id, 10)
|
||||
}
|
||||
|
||||
func (m *GitLabProvider) GetUserFromJson(data io.Reader) (*model.User, error) {
|
||||
func (m *GitLabProvider) GetUserFromJson(data io.Reader, tokenUser *model.User) (*model.User, error) {
|
||||
glu, err := gitLabUserFromJson(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -102,3 +102,11 @@ func (m *GitLabProvider) GetUserFromJson(data io.Reader) (*model.User, error) {
|
||||
|
||||
return userFromGitLabUser(glu), nil
|
||||
}
|
||||
|
||||
func (m *GitLabProvider) GetSSOSettings(config *model.Config, service string) (*model.SSOSettings, error) {
|
||||
return &config.GitLabSettings, nil
|
||||
}
|
||||
|
||||
func (m *GitLabProvider) GetUserFromIdToken(idToken string) (*model.User, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ type Features struct {
|
||||
MFA *bool `json:"mfa"`
|
||||
GoogleOAuth *bool `json:"google_oauth"`
|
||||
Office365OAuth *bool `json:"office365_oauth"`
|
||||
OpenId *bool `json:"openid"`
|
||||
Compliance *bool `json:"compliance"`
|
||||
Cluster *bool `json:"cluster"`
|
||||
Metrics *bool `json:"metrics"`
|
||||
@@ -95,6 +96,7 @@ func (f *Features) ToMap() map[string]interface{} {
|
||||
"mfa": *f.MFA,
|
||||
"google": *f.GoogleOAuth,
|
||||
"office365": *f.Office365OAuth,
|
||||
"openid": *f.OpenId,
|
||||
"compliance": *f.Compliance,
|
||||
"cluster": *f.Cluster,
|
||||
"metrics": *f.Metrics,
|
||||
@@ -145,6 +147,10 @@ func (f *Features) SetDefaults() {
|
||||
f.Office365OAuth = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.OpenId == nil {
|
||||
f.OpenId = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.Compliance == nil {
|
||||
f.Compliance = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
@@ -34,14 +34,16 @@ func (o *SwitchRequest) EmailToOAuth() bool {
|
||||
(o.NewService == USER_AUTH_SERVICE_SAML ||
|
||||
o.NewService == USER_AUTH_SERVICE_GITLAB ||
|
||||
o.NewService == SERVICE_GOOGLE ||
|
||||
o.NewService == SERVICE_OFFICE365)
|
||||
o.NewService == SERVICE_OFFICE365 ||
|
||||
o.NewService == SERVICE_OPENID)
|
||||
}
|
||||
|
||||
func (o *SwitchRequest) OAuthToEmail() bool {
|
||||
return (o.CurrentService == USER_AUTH_SERVICE_SAML ||
|
||||
o.CurrentService == USER_AUTH_SERVICE_GITLAB ||
|
||||
o.CurrentService == SERVICE_GOOGLE ||
|
||||
o.CurrentService == SERVICE_OFFICE365) && o.NewService == USER_AUTH_SERVICE_EMAIL
|
||||
o.CurrentService == SERVICE_OFFICE365 ||
|
||||
o.CurrentService == SERVICE_OPENID) && o.NewService == USER_AUTH_SERVICE_EMAIL
|
||||
}
|
||||
|
||||
func (o *SwitchRequest) EmailToLdap() bool {
|
||||
|
||||
Ссылка в новой задаче
Block a user