2019-11-29 12:59:40 +01:00
|
|
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
|
|
|
// See LICENSE.txt for license information.
|
2017-03-28 04:58:19 -04:00
|
|
|
|
|
|
|
|
package utils
|
|
|
|
|
|
|
|
|
|
import (
|
2018-02-07 11:05:46 -06:00
|
|
|
"crypto"
|
|
|
|
|
"crypto/rand"
|
|
|
|
|
"encoding/base64"
|
2018-02-02 07:29:11 -06:00
|
|
|
"fmt"
|
|
|
|
|
"html/template"
|
2017-03-28 04:58:19 -04:00
|
|
|
"net/http"
|
2017-04-20 09:55:02 -04:00
|
|
|
"net/url"
|
2018-06-21 14:31:51 -04:00
|
|
|
"path"
|
2017-03-28 04:58:19 -04:00
|
|
|
"strings"
|
2017-04-20 09:55:02 -04:00
|
|
|
|
2019-11-28 14:39:38 +01:00
|
|
|
"github.com/mattermost/mattermost-server/v5/model"
|
2017-03-28 04:58:19 -04:00
|
|
|
)
|
|
|
|
|
|
2017-11-22 15:58:03 -06:00
|
|
|
func CheckOrigin(r *http.Request, allowedOrigins string) bool {
|
2017-03-28 04:58:19 -04:00
|
|
|
origin := r.Header.Get("Origin")
|
2018-08-24 06:09:48 -04:00
|
|
|
if origin == "" {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-22 15:58:03 -06:00
|
|
|
if allowedOrigins == "*" {
|
2017-07-13 14:02:33 -07:00
|
|
|
return true
|
|
|
|
|
}
|
2017-11-22 15:58:03 -06:00
|
|
|
for _, allowed := range strings.Split(allowedOrigins, " ") {
|
2017-07-13 14:02:33 -07:00
|
|
|
if allowed == origin {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false
|
2017-03-28 04:58:19 -04:00
|
|
|
}
|
|
|
|
|
|
2017-11-22 15:58:03 -06:00
|
|
|
func OriginChecker(allowedOrigins string) func(*http.Request) bool {
|
|
|
|
|
return func(r *http.Request) bool {
|
|
|
|
|
return CheckOrigin(r, allowedOrigins)
|
2017-03-28 04:58:19 -04:00
|
|
|
}
|
|
|
|
|
}
|
2017-04-20 09:55:02 -04:00
|
|
|
|
2018-06-21 14:31:51 -04:00
|
|
|
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{
|
2018-02-07 11:05:46 -06:00
|
|
|
"message": []string{err.Message},
|
|
|
|
|
}, s)
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-21 14:31:51 -04:00
|
|
|
func RenderWebError(config *model.Config, w http.ResponseWriter, r *http.Request, status int, params url.Values, s crypto.Signer) {
|
2018-02-07 11:05:46 -06:00
|
|
|
queryString := params.Encode()
|
|
|
|
|
|
2018-06-21 14:31:51 -04:00
|
|
|
subpath, _ := GetSubpathFromConfig(config)
|
|
|
|
|
|
2018-02-07 11:05:46 -06:00
|
|
|
h := crypto.SHA256
|
|
|
|
|
sum := h.New()
|
2018-06-21 14:31:51 -04:00
|
|
|
sum.Write([]byte(path.Join(subpath, "error") + "?" + queryString))
|
2018-02-07 11:05:46 -06:00
|
|
|
signature, err := s.Sign(rand.Reader, sum.Sum(nil), h)
|
|
|
|
|
if err != nil {
|
|
|
|
|
http.Error(w, "", http.StatusInternalServerError)
|
|
|
|
|
return
|
2017-04-20 09:55:02 -04:00
|
|
|
}
|
2018-06-21 14:31:51 -04:00
|
|
|
destination := path.Join(subpath, "error") + "?" + queryString + "&s=" + base64.URLEncoding.EncodeToString(signature)
|
2017-04-20 09:55:02 -04:00
|
|
|
|
2018-02-02 07:29:11 -06:00
|
|
|
if status >= 300 && status < 400 {
|
|
|
|
|
http.Redirect(w, r, destination, status)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-14 18:09:04 -04:00
|
|
|
w.Header().Set("Content-Type", "text/html")
|
2018-02-02 07:29:11 -06:00
|
|
|
w.WriteHeader(status)
|
|
|
|
|
fmt.Fprintln(w, `<!DOCTYPE html><html><head></head>`)
|
|
|
|
|
fmt.Fprintln(w, `<body onload="window.location = '`+template.HTMLEscapeString(template.JSEscapeString(destination))+`'">`)
|
|
|
|
|
fmt.Fprintln(w, `<noscript><meta http-equiv="refresh" content="0; url=`+template.HTMLEscapeString(destination)+`"></noscript>`)
|
|
|
|
|
fmt.Fprintln(w, `<a href="`+template.HTMLEscapeString(destination)+`" style="color: #c0c0c0;">...</a>`)
|
|
|
|
|
fmt.Fprintln(w, `</body></html>`)
|
2017-04-20 09:55:02 -04:00
|
|
|
}
|