mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
* 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
166 lines
4.3 KiB
Go
166 lines
4.3 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See License.txt for license information.
|
|
|
|
package web
|
|
|
|
import (
|
|
b64 "encoding/base64"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/mattermost/mattermost-server/mlog"
|
|
"github.com/mattermost/mattermost-server/model"
|
|
)
|
|
|
|
func (w *Web) InitSaml() {
|
|
w.MainRouter.Handle("/login/sso/saml", w.NewHandler(loginWithSaml)).Methods("GET")
|
|
w.MainRouter.Handle("/login/sso/saml", w.NewHandler(completeSaml)).Methods("POST")
|
|
}
|
|
|
|
func loginWithSaml(c *Context, w http.ResponseWriter, r *http.Request) {
|
|
samlInterface := c.App.Saml
|
|
|
|
if samlInterface == nil {
|
|
c.Err = model.NewAppError("loginWithSaml", "api.user.saml.not_available.app_error", nil, "", http.StatusFound)
|
|
return
|
|
}
|
|
|
|
teamId, err := c.App.GetTeamIdFromQuery(r.URL.Query())
|
|
if err != nil {
|
|
c.Err = err
|
|
return
|
|
}
|
|
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 := ""
|
|
|
|
if len(action) != 0 {
|
|
relayProps["team_id"] = teamId
|
|
relayProps["action"] = action
|
|
if action == model.OAUTH_ACTION_EMAIL_TO_SSO {
|
|
relayProps["email"] = r.URL.Query().Get("email")
|
|
}
|
|
}
|
|
|
|
if len(redirectTo) != 0 {
|
|
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)))
|
|
}
|
|
|
|
if data, err := samlInterface.BuildRequest(relayState); err != nil {
|
|
c.Err = err
|
|
return
|
|
} else {
|
|
w.Header().Set("Content-Type", "application/x-www-form-urlencoded")
|
|
http.Redirect(w, r, data.URL, http.StatusFound)
|
|
}
|
|
}
|
|
|
|
func completeSaml(c *Context, w http.ResponseWriter, r *http.Request) {
|
|
samlInterface := c.App.Saml
|
|
|
|
if samlInterface == nil {
|
|
c.Err = model.NewAppError("completeSaml", "api.user.saml.not_available.app_error", nil, "", http.StatusFound)
|
|
return
|
|
}
|
|
|
|
//Validate that the user is with SAML and all that
|
|
encodedXML := r.FormValue("SAMLResponse")
|
|
relayState := r.FormValue("RelayState")
|
|
|
|
relayProps := make(map[string]string)
|
|
if len(relayState) > 0 {
|
|
stateStr := ""
|
|
if b, err := b64.StdEncoding.DecodeString(relayState); err != nil {
|
|
c.Err = model.NewAppError("completeSaml", "api.user.authorize_oauth_user.invalid_state.app_error", nil, err.Error(), http.StatusFound)
|
|
return
|
|
} else {
|
|
stateStr = string(b)
|
|
}
|
|
relayProps = model.MapFromJson(strings.NewReader(stateStr))
|
|
}
|
|
|
|
action := relayProps["action"]
|
|
if user, err := samlInterface.DoLogin(encodedXML, relayProps); err != nil {
|
|
if action == model.OAUTH_ACTION_MOBILE {
|
|
err.Translate(c.T)
|
|
w.Write([]byte(err.ToJson()))
|
|
} else {
|
|
c.Err = err
|
|
c.Err.StatusCode = http.StatusFound
|
|
}
|
|
return
|
|
} else {
|
|
if err := c.App.CheckUserAllAuthenticationCriteria(user, ""); err != nil {
|
|
c.Err = err
|
|
c.Err.StatusCode = http.StatusFound
|
|
return
|
|
}
|
|
|
|
switch action {
|
|
case model.OAUTH_ACTION_SIGNUP:
|
|
teamId := relayProps["team_id"]
|
|
if len(teamId) > 0 {
|
|
c.App.Go(func() {
|
|
if err := c.App.AddUserToTeamByTeamId(teamId, user); err != nil {
|
|
mlog.Error(err.Error())
|
|
} else {
|
|
c.App.AddDirectChannels(teamId, user)
|
|
}
|
|
})
|
|
}
|
|
case model.OAUTH_ACTION_EMAIL_TO_SSO:
|
|
if err := c.App.RevokeAllSessions(user.Id); err != nil {
|
|
c.Err = err
|
|
return
|
|
}
|
|
c.LogAuditWithUserId(user.Id, "Revoked all sessions for user")
|
|
c.App.Go(func() {
|
|
if err := c.App.SendSignInChangeEmail(user.Email, strings.Title(model.USER_AUTH_SERVICE_SAML)+" SSO", user.Locale, c.App.GetSiteURL()); err != nil {
|
|
mlog.Error(err.Error())
|
|
}
|
|
})
|
|
}
|
|
|
|
session, err := c.App.DoLogin(w, r, user, "")
|
|
if err != nil {
|
|
c.Err = err
|
|
return
|
|
}
|
|
|
|
c.Session = *session
|
|
|
|
if val, ok := relayProps["redirect_to"]; ok {
|
|
http.Redirect(w, r, c.GetSiteURLHeader()+val, http.StatusFound)
|
|
return
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
}
|