124 lines
3.5 KiB
Go
124 lines
3.5 KiB
Go
package utils
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"git.nutfactory.org/hoernschen/Matrix/config"
|
|
)
|
|
|
|
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"`
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
func CheckAuthHeader(r *http.Request, content string) (response *ErrorResponse) {
|
|
if !config.AuthentificationCheck {
|
|
return
|
|
}
|
|
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]
|
|
if !strings.Contains(keys[1], "ed25519") {
|
|
response = &ErrorResponse{ErrorMessage: "Missing ed25519 Signature Key"}
|
|
return
|
|
}
|
|
key := strings.Split(strings.Replace(strings.Split(keys[1], "=")[1], "\"", "", 2), ":")[1]
|
|
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
|
|
}
|
|
correct := VerifySignature([]byte(key), requestSummaryString, signature)
|
|
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
|
|
}
|
|
authHeader = fmt.Sprintf("X-Matrix origin=%s,key=%s,sig=%s", config.Homeserver, config.KeyId, Sign(SigningContent))
|
|
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
|
|
}
|
|
|
|
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
|
|
|
|
}
|