package utils import ( "bytes" "encoding/json" "fmt" "net/http" "strings" "nutfactory.org/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) (response *ErrorResponse) { 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[2], "ed25519") { response = &ErrorResponse{ErrorMessage: "Missing ed25519 Signature Key"} return } key := strings.Split(strings.Replace(strings.Split(keys[2], "=")[1], "\"", "", 2), ":")[1] signature := strings.Replace(strings.Split(keys[2], "=")[1], "\"", "", 2) buf := new(bytes.Buffer) buf.ReadFrom(r.Body) content := buf.String() 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, []byte(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 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 }