Commit 3fcecd52 authored by Chris Duarte's avatar Chris Duarte Committed by Christopher Speller

Support for Embeded chat (#9129)

* Add ucLive support

crazy testing

lovely logs

more cookie work arounds

Added Access-Control-Expose-Headers to user login

Add complete_saml_body template and revert loginWithSaml endpoint

Set Access-Control-Allow-Credentials to true in user login

Login via email instead of username

Clean up code

Add comment to give some context

Move faml logic into saml function

Communicate via chrome sendMessage api

Remove unused code

Add config to support multiple extensions

Clean up embedded complete_saml template

Fix indentation for templates

Added license header to extension.go

Add EnableExperimentalExtensions flag

Extension validated for email auth

Clean up api auth code

Remove complete_saml_body.html

* Add extension support in saml

* Clean up code

* Clean up extension validation
parent 6b27b74f
// 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
}
......@@ -194,6 +194,10 @@
"LoginButtonBorderColor": "",
"LoginButtonTextColor": ""
},
"ExtensionSettings": {
"EnableExperimentalExtensions": false,
"AllowedExtensionsIDs": []
},
"RateLimitSettings": {
"Enable": false,
"PerSec": 10,
......
......@@ -2166,6 +2166,22 @@
"id": "api.user.send_deactivate_email_and_forget.failed.error",
"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"
......
......@@ -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 {
......
......@@ -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 {
......
{{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}}
......@@ -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)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment