diff options
-rw-r--r-- | app/extension.go | 82 | ||||
-rw-r--r-- | config/default.json | 4 | ||||
-rw-r--r-- | i18n/en.json | 16 | ||||
-rw-r--r-- | model/config.go | 17 | ||||
-rw-r--r-- | model/oauth.go | 1 | ||||
-rw-r--r-- | templates/complete_saml_extension_body.html | 30 | ||||
-rw-r--r-- | web/saml.go | 17 |
7 files changed, 167 insertions, 0 deletions
diff --git a/app/extension.go b/app/extension.go new file mode 100644 index 000000000..d0226bba5 --- /dev/null +++ b/app/extension.go @@ -0,0 +1,82 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package app + +import ( + "github.com/mattermost/mattermost-server/model" + "html/template" + "net/http" +) + +func (a *App) isExtensionSupportEnabled() bool { + return *a.Config().ExtensionSettings.EnableExperimentalExtensions +} + +func (a *App) isExtensionValid(extensionId string) bool { + extensionIsValid := false + extensionIDs := a.Config().ExtensionSettings.AllowedExtensionsIDs + + for _, id := range extensionIDs { + if extensionId == id { + extensionIsValid = true + } + } + + return extensionIsValid +} + +func (a *App) ValidateExtension(extensionId string) *model.AppError { + enabled := a.isExtensionSupportEnabled() + if !enabled { + return model.NewAppError("completeSaml", "api.user.saml.extension_unsupported", nil, "", http.StatusInternalServerError) + } + + valid := a.isExtensionValid(extensionId) + if !valid { + params := map[string]interface{}{"ExtensionId": extensionId} + return model.NewAppError("completeSaml", "api.user.saml.invalid_extension", params, "", http.StatusInternalServerError) + } + + return nil +} + +func (a *App) SendMessageToExtension(w http.ResponseWriter, extensionId string, token string) *model.AppError { + var err error + var t *template.Template + if len(extensionId) == 0 { + return model.NewAppError("completeSaml", "api.user.saml.extension_id.app_error", nil, "", http.StatusInternalServerError) + } + + t = template.New("complete_saml_extension_body") + t, err = t.ParseFiles("templates/complete_saml_extension_body.html") + + if err != nil { + return model.NewAppError("completeSaml", "api.user.saml.app_error", nil, "err="+err.Error(), http.StatusInternalServerError) + } + + w.Header().Set("Content-Type", "text/html") + w.WriteHeader(http.StatusOK) + + var errMessage string + if len(token) == 0 { + loginError := model.NewAppError("completeSaml", "api.user.saml.app_error", nil, "", http.StatusInternalServerError) + errMessage = loginError.Message + } + + data := struct { + ExtensionId string + Token string + Error string + }{ + extensionId, + token, + errMessage, + } + + if err := t.Execute(w, data); err != nil { + return model.NewAppError("completeSaml", "api.user.saml.app_error", nil, "err="+err.Error(), http.StatusInternalServerError) + } + + return nil +} diff --git a/config/default.json b/config/default.json index cb60611ba..cd85eda50 100644 --- a/config/default.json +++ b/config/default.json @@ -194,6 +194,10 @@ "LoginButtonBorderColor": "", "LoginButtonTextColor": "" }, + "ExtensionSettings": { + "EnableExperimentalExtensions": false, + "AllowedExtensionsIDs": [] + }, "RateLimitSettings": { "Enable": false, "PerSec": 10, diff --git a/i18n/en.json b/i18n/en.json index 9493a36b0..aad77aeb5 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -2167,6 +2167,22 @@ "translation": "Failed to send the deactivate account email successfully" }, { + "id": "api.user.saml.app_error", + "translation": "Unable to process SAML login request." + }, + { + "id": "api.user.saml.extension_unsupported", + "translation": "Extensions are not supported." + }, + { + "id": "api.user.saml.extension_id.app_error", + "translation": "Invalid extension id" + }, + { + "id": "api.user.saml.invalid_extension", + "translation": "Extension with extension_id={{.ExtensionId}} is not supported." + }, + { "id": "api.user.send_email_change_email_and_forget.error", "translation": "Failed to send email change notification email successfully" }, diff --git a/model/config.go b/model/config.go index 7c9643b75..904668606 100644 --- a/model/config.go +++ b/model/config.go @@ -907,6 +907,21 @@ func (s *EmailSettings) SetDefaults() { } } +type ExtensionSettings struct { + EnableExperimentalExtensions *bool + AllowedExtensionsIDs []string +} + +func (s *ExtensionSettings) SetDefaults() { + if s.EnableExperimentalExtensions == nil { + s.EnableExperimentalExtensions = NewBool(false) + } + + if s.AllowedExtensionsIDs == nil { + s.AllowedExtensionsIDs = []string{} + } +} + type RateLimitSettings struct { Enable *bool PerSec *int @@ -1870,6 +1885,7 @@ type Config struct { PasswordSettings PasswordSettings FileSettings FileSettings EmailSettings EmailSettings + ExtensionSettings ExtensionSettings RateLimitSettings RateLimitSettings PrivacySettings PrivacySettings SupportSettings SupportSettings @@ -1967,6 +1983,7 @@ func (o *Config) SetDefaults() { o.MessageExportSettings.SetDefaults() o.TimezoneSettings.SetDefaults() o.DisplaySettings.SetDefaults() + o.ExtensionSettings.SetDefaults() } func (o *Config) IsValid() *AppError { diff --git a/model/oauth.go b/model/oauth.go index c92b1ec41..0ea1aa4e2 100644 --- a/model/oauth.go +++ b/model/oauth.go @@ -17,6 +17,7 @@ const ( OAUTH_ACTION_EMAIL_TO_SSO = "email_to_sso" OAUTH_ACTION_SSO_TO_EMAIL = "sso_to_email" OAUTH_ACTION_MOBILE = "mobile" + OAUTH_ACTION_CLIENT = "client" ) type OAuthApp struct { diff --git a/templates/complete_saml_extension_body.html b/templates/complete_saml_extension_body.html new file mode 100644 index 000000000..0c99ecbdc --- /dev/null +++ b/templates/complete_saml_extension_body.html @@ -0,0 +1,30 @@ +{{define "complete_saml_extension_body"}} + +<html> + <head> + <script> + document.addEventListener("DOMContentLoaded", function(event) { + var extensionId = {{.ExtensionId}}; + + if (!extensionId) { + return; + } + + chrome.runtime.sendMessage( + extensionId, + { + value: {{.Token}}, + error: {{.Error}} + }, + function(response) { + } + ); + }); + </script> + </head> + <body> + Login Successful + </body> +</html> + +{{end}} diff --git a/web/saml.go b/web/saml.go index 9cf93bdab..f5400a378 100644 --- a/web/saml.go +++ b/web/saml.go @@ -32,6 +32,7 @@ func loginWithSaml(c *Context, w http.ResponseWriter, r *http.Request) { } action := r.URL.Query().Get("action") redirectTo := r.URL.Query().Get("redirect_to") + extensionId := r.URL.Query().Get("extension_id") relayProps := map[string]string{} relayState := "" @@ -47,6 +48,15 @@ func loginWithSaml(c *Context, w http.ResponseWriter, r *http.Request) { relayProps["redirect_to"] = redirectTo } + if len(extensionId) != 0 { + relayProps["extension_id"] = extensionId + err := c.App.ValidateExtension(extensionId) + if err != nil { + c.Err = err + return + } + } + if len(relayProps) > 0 { relayState = b64.StdEncoding.EncodeToString([]byte(model.MapToJson(relayProps))) } @@ -141,6 +151,13 @@ func completeSaml(c *Context, w http.ResponseWriter, r *http.Request) { if action == model.OAUTH_ACTION_MOBILE { ReturnStatusOK(w) + } else if action == model.OAUTH_ACTION_CLIENT { + err = c.App.SendMessageToExtension(w, relayProps["extension_id"], c.Session.Token) + + if err != nil { + c.Err = err + return + } } else { http.Redirect(w, r, c.GetSiteURLHeader(), http.StatusFound) } |