github.com/gigforks/mattermost-server@v4.9.1-0.20180619094218-800d97fa55d0+incompatible/utils/api.go (about)

     1  // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package utils
     5  
     6  import (
     7  	"crypto"
     8  	"crypto/rand"
     9  	"encoding/base64"
    10  	"fmt"
    11  	"html/template"
    12  	"net/http"
    13  	"net/url"
    14  	"strings"
    15  
    16  	"github.com/mattermost/mattermost-server/model"
    17  )
    18  
    19  func CheckOrigin(r *http.Request, allowedOrigins string) bool {
    20  	origin := r.Header.Get("Origin")
    21  	if allowedOrigins == "*" {
    22  		return true
    23  	}
    24  	for _, allowed := range strings.Split(allowedOrigins, " ") {
    25  		if allowed == origin {
    26  			return true
    27  		}
    28  	}
    29  	return false
    30  }
    31  
    32  func OriginChecker(allowedOrigins string) func(*http.Request) bool {
    33  	return func(r *http.Request) bool {
    34  		return CheckOrigin(r, allowedOrigins)
    35  	}
    36  }
    37  
    38  func RenderWebAppError(w http.ResponseWriter, r *http.Request, err *model.AppError, s crypto.Signer) {
    39  	RenderWebError(w, r, err.StatusCode, url.Values{
    40  		"message": []string{err.Message},
    41  	}, s)
    42  }
    43  
    44  func RenderWebError(w http.ResponseWriter, r *http.Request, status int, params url.Values, s crypto.Signer) {
    45  	queryString := params.Encode()
    46  
    47  	h := crypto.SHA256
    48  	sum := h.New()
    49  	sum.Write([]byte("/error?" + queryString))
    50  	signature, err := s.Sign(rand.Reader, sum.Sum(nil), h)
    51  	if err != nil {
    52  		http.Error(w, "", http.StatusInternalServerError)
    53  		return
    54  	}
    55  	destination := "/error?" + queryString + "&s=" + base64.URLEncoding.EncodeToString(signature)
    56  
    57  	if status >= 300 && status < 400 {
    58  		http.Redirect(w, r, destination, status)
    59  		return
    60  	}
    61  
    62  	w.Header().Set("Content-Type", "text/html")
    63  	w.WriteHeader(status)
    64  	fmt.Fprintln(w, `<!DOCTYPE html><html><head></head>`)
    65  	fmt.Fprintln(w, `<body onload="window.location = '`+template.HTMLEscapeString(template.JSEscapeString(destination))+`'">`)
    66  	fmt.Fprintln(w, `<noscript><meta http-equiv="refresh" content="0; url=`+template.HTMLEscapeString(destination)+`"></noscript>`)
    67  	fmt.Fprintln(w, `<a href="`+template.HTMLEscapeString(destination)+`" style="color: #c0c0c0;">...</a>`)
    68  	fmt.Fprintln(w, `</body></html>`)
    69  }