github.com/xzl8028/xenia-server@v0.0.0-20190809101854-18450a97da63/utils/api.go (about)

     1  // Copyright (c) 2017-present Xenia, 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  	"path"
    15  	"strings"
    16  
    17  	"github.com/xzl8028/xenia-server/model"
    18  )
    19  
    20  func CheckOrigin(r *http.Request, allowedOrigins string) bool {
    21  	origin := r.Header.Get("Origin")
    22  	if origin == "" {
    23  		return true
    24  	}
    25  
    26  	if allowedOrigins == "*" {
    27  		return true
    28  	}
    29  	for _, allowed := range strings.Split(allowedOrigins, " ") {
    30  		if allowed == origin {
    31  			return true
    32  		}
    33  	}
    34  	return false
    35  }
    36  
    37  func OriginChecker(allowedOrigins string) func(*http.Request) bool {
    38  	return func(r *http.Request) bool {
    39  		return CheckOrigin(r, allowedOrigins)
    40  	}
    41  }
    42  
    43  func RenderWebAppError(config *model.Config, w http.ResponseWriter, r *http.Request, err *model.AppError, s crypto.Signer) {
    44  	RenderWebError(config, w, r, err.StatusCode, url.Values{
    45  		"message": []string{err.Message},
    46  	}, s)
    47  }
    48  
    49  func RenderWebError(config *model.Config, w http.ResponseWriter, r *http.Request, status int, params url.Values, s crypto.Signer) {
    50  	queryString := params.Encode()
    51  
    52  	subpath, _ := GetSubpathFromConfig(config)
    53  
    54  	h := crypto.SHA256
    55  	sum := h.New()
    56  	sum.Write([]byte(path.Join(subpath, "error") + "?" + queryString))
    57  	signature, err := s.Sign(rand.Reader, sum.Sum(nil), h)
    58  	if err != nil {
    59  		http.Error(w, "", http.StatusInternalServerError)
    60  		return
    61  	}
    62  	destination := path.Join(subpath, "error") + "?" + queryString + "&s=" + base64.URLEncoding.EncodeToString(signature)
    63  
    64  	if status >= 300 && status < 400 {
    65  		http.Redirect(w, r, destination, status)
    66  		return
    67  	}
    68  
    69  	w.Header().Set("Content-Type", "text/html")
    70  	w.WriteHeader(status)
    71  	fmt.Fprintln(w, `<!DOCTYPE html><html><head></head>`)
    72  	fmt.Fprintln(w, `<body onload="window.location = '`+template.HTMLEscapeString(template.JSEscapeString(destination))+`'">`)
    73  	fmt.Fprintln(w, `<noscript><meta http-equiv="refresh" content="0; url=`+template.HTMLEscapeString(destination)+`"></noscript>`)
    74  	fmt.Fprintln(w, `<a href="`+template.HTMLEscapeString(destination)+`" style="color: #c0c0c0;">...</a>`)
    75  	fmt.Fprintln(w, `</body></html>`)
    76  }