Matrix/utils/requestChecker.go

125 lines
3.5 KiB
Go
Raw Normal View History

package utils
import (
"encoding/json"
2020-10-11 21:11:30 +00:00
"fmt"
2020-10-17 10:07:39 +00:00
"log"
"net/http"
"strings"
2020-10-11 21:11:30 +00:00
2020-10-12 14:16:28 +00:00
"git.nutfactory.org/hoernschen/Matrix/config"
)
2020-10-11 21:11:30 +00:00
type RequestSummary struct {
Method string `json:"method,omitempty"`
Uri string `json:"uri,omitempty"`
Origin string `json:"origin,omitempty"`
Destination string `json:"destination,omitempty"`
Content string `json:"content,omitempty"`
Signatures map[string]map[string]string `json:"signatures,omitempty"`
}
type ErrorResponse struct {
ErrorCode string `json:"errcode,omitempty"`
ErrorMessage string `json:"error,omitempty"`
RetryTime int `json:"retry_after_ms,omitempty"`
}
2020-10-04 12:22:52 +00:00
func CheckRequest(r *http.Request) (response *ErrorResponse) {
if !strings.Contains(r.Header.Get("Content-Type"), "application/json") {
response = &ErrorResponse{ErrorMessage: "Content Type not JSON"}
}
return
}
2020-10-17 10:07:39 +00:00
func CheckAuthHeader(r *http.Request, content string) (response *ErrorResponse) {
if !config.AuthentificationCheck {
return
}
2020-10-11 21:11:30 +00:00
authHeader := r.Header.Get("Authorization")
if authHeader == "" || !strings.Contains(authHeader, "X-Matrix") {
response = &ErrorResponse{ErrorMessage: "Missing Authorization Header"}
return
}
keys := strings.Split(authHeader, ",")
origin := strings.Split(keys[0], "=")[1]
2020-10-17 10:07:39 +00:00
if !strings.Contains(keys[1], "ed25519") {
2020-10-11 21:11:30 +00:00
response = &ErrorResponse{ErrorMessage: "Missing ed25519 Signature Key"}
return
}
2020-10-17 10:07:39 +00:00
key := strings.Split(strings.Replace(strings.Split(keys[1], "=")[1], "\"", "", 2), ":")[1]
2020-10-11 21:11:30 +00:00
signature := strings.Replace(strings.Split(keys[2], "=")[1], "\"", "", 2)
requestSummary := RequestSummary{
Method: r.Method,
Uri: r.RequestURI,
Origin: origin,
Destination: config.Homeserver,
Content: content,
}
requestSummaryString, err := json.Marshal(requestSummary)
if err != nil {
response = &ErrorResponse{ErrorMessage: "Error Creating Auth JSON String"}
return
}
2020-10-17 10:07:39 +00:00
correct := VerifySignature([]byte(key), requestSummaryString, signature)
2020-10-11 21:11:30 +00:00
if !correct {
response = &ErrorResponse{ErrorMessage: "Signature in Auth Header is incorrect"}
return
}
return
}
func CreateAuthHeader(method string, uri string, destination string, content string) (authHeader string, err error) {
requestSummary := RequestSummary{
Method: method,
Uri: uri,
Origin: config.Homeserver,
Destination: destination,
Content: content,
}
SigningContent, err := json.Marshal(requestSummary)
if err != nil {
return
}
2020-10-17 10:07:39 +00:00
authHeader = fmt.Sprintf("X-Matrix origin=%s,key=%s,sig=%s", config.Homeserver, config.KeyId, Sign(SigningContent))
2020-10-11 21:11:30 +00:00
return
}
func GetAccessToken(r *http.Request) (token string, response *ErrorResponse) {
token = r.URL.Query().Get("access_token")
if token == "" {
token = r.Header.Get("Authorization")
if token == "" || !strings.Contains(token, "Bearer") {
response = &ErrorResponse{ErrorCode: "M_MISSING_TOKEN"}
} else {
token = strings.Split(token, " ")[1]
}
}
return
}
2020-10-17 10:07:39 +00:00
func HandleHTTPError(res *http.Response) (response *ErrorResponse) {
log.Printf("Statuscode %s", res.Status)
response = &ErrorResponse{}
decoder := json.NewDecoder(res.Body)
err := decoder.Decode(response)
if err != nil {
log.Printf("Error not parseable")
return
}
log.Printf("%s (%s)", response.ErrorMessage, response.ErrorCode)
return
}
func IsJSONString(s string) bool {
var js string
return json.Unmarshal([]byte(s), &js) == nil
}
func IsJSON(s string) bool {
var js interface{}
return json.Unmarshal([]byte(s), &js) == nil
}