// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. package utils import ( "crypto" "crypto/rand" "encoding/base64" "fmt" "html/template" "net/http" "net/url" "path" "slices" "strings" "github.com/mattermost/mattermost/server/public/model" "github.com/mattermost/mattermost/server/public/shared/i18n" ) func CheckOrigin(r *http.Request, allowedOrigins string) bool { origin := r.Header.Get("Origin") if origin == "" { return true } if allowedOrigins == "*" { return true } return slices.Contains(strings.Split(allowedOrigins, " "), origin) } func OriginChecker(allowedOrigins string) func(*http.Request) bool { return func(r *http.Request) bool { return CheckOrigin(r, allowedOrigins) } } // CheckEmbeddedCookie returns true if the MMEMBED cookie is set to 1. // MMEMBED is set via any plugin that facilitates Mattermost embedded in an iframe (e.g. mattermost-plugin-msteams-sync). func CheckEmbeddedCookie(r *http.Request) bool { cookie, err := r.Cookie("MMEMBED") if err != nil { return false } return cookie.Value == "1" } func RenderWebAppError(config *model.Config, w http.ResponseWriter, r *http.Request, err *model.AppError, s crypto.Signer) { RenderWebError(config, w, r, err.StatusCode, url.Values{ "message": []string{err.Message}, }, s) } func RenderWebError(config *model.Config, w http.ResponseWriter, r *http.Request, status int, params url.Values, s crypto.Signer) { queryString := params.Encode() subpath, _ := GetSubpathFromConfig(config) h := crypto.SHA256 sum := h.New() sum.Write([]byte(path.Join(subpath, "error") + "?" + queryString)) signature, err := s.Sign(rand.Reader, sum.Sum(nil), h) if err != nil { http.Error(w, "", http.StatusInternalServerError) return } destination := path.Join(subpath, "error") + "?" + queryString + "&s=" + base64.URLEncoding.EncodeToString(signature) if status >= 300 && status < 400 { http.Redirect(w, r, destination, status) return } w.Header().Set("Content-Type", "text/html") w.WriteHeader(status) fmt.Fprintln(w, `
`) fmt.Fprintln(w, ``) fmt.Fprintln(w, ``) fmt.Fprintln(w, ``) fmt.Fprintln(w, `...`) fmt.Fprintln(w, ``) } func RenderMobileAuthComplete(w http.ResponseWriter, redirectURL string) { var link = template.HTMLEscapeString(redirectURL) RenderMobileMessage(w, ``+i18n.T("api.oauth.redirecting_back")+`
`+i18n.T("api.oauth.click_redirect", model.StringInterface{"Link": link})+`
`) } func RenderMobileError(config *model.Config, w http.ResponseWriter, err *model.AppError, redirectURL string) { var link = template.HTMLEscapeString(redirectURL) u, redirectErr := url.Parse(redirectURL) if redirectErr != nil || !slices.Contains(config.NativeAppSettings.AppCustomURLSchemes, u.Scheme) { link = *config.ServiceSettings.SiteURL } RenderMobileMessage(w, ``+err.Message+`
`+i18n.T("api.back_to_app", map[string]any{"SiteName": config.TeamSettings.SiteName})+` `) } func RenderMobileMessage(w http.ResponseWriter, message string) { w.Header().Set("Content-Type", "text/html") fmt.Fprintln(w, ` `) }