2022-10-21 14:18:02 +00:00
|
|
|
// mautrix-groupme - A Matrix-GroupMe puppeting bridge.
|
|
|
|
// Copyright (C) 2022 Sumner Evans, Karmanyaah Malhotra
|
2020-02-09 18:32:14 +00:00
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Affero General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
log "maunium.net/go/maulogger/v2"
|
|
|
|
|
2020-05-08 19:32:22 +00:00
|
|
|
"maunium.net/go/mautrix/id"
|
2020-02-09 18:32:14 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type ProvisioningAPI struct {
|
2022-10-21 19:02:33 +00:00
|
|
|
bridge *GMBridge
|
2020-02-09 18:32:14 +00:00
|
|
|
log log.Logger
|
|
|
|
}
|
|
|
|
|
|
|
|
func (prov *ProvisioningAPI) Init() {
|
|
|
|
prov.log = prov.bridge.Log.Sub("Provisioning")
|
2022-10-21 22:04:21 +00:00
|
|
|
prov.log.Debugln("Enabling provisioning API at", prov.bridge.Config.Bridge.Provisioning.Prefix)
|
|
|
|
r := prov.bridge.AS.Router.PathPrefix(prov.bridge.Config.Bridge.Provisioning.Prefix).Subrouter()
|
2020-02-09 18:32:14 +00:00
|
|
|
r.Use(prov.AuthMiddleware)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (prov *ProvisioningAPI) AuthMiddleware(h http.Handler) http.Handler {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
auth := r.Header.Get("Authorization")
|
2020-11-24 14:48:29 +00:00
|
|
|
if len(auth) == 0 && strings.HasSuffix(r.URL.Path, "/login") {
|
|
|
|
authParts := strings.Split(r.Header.Get("Sec-WebSocket-Protocol"), ",")
|
|
|
|
for _, part := range authParts {
|
|
|
|
part = strings.TrimSpace(part)
|
2023-03-20 00:31:16 +00:00
|
|
|
if strings.HasPrefix(part, "com.beeper.groupme.auth-") {
|
|
|
|
auth = part[len("com.beeper.groupme.auth-"):]
|
2020-11-24 14:48:29 +00:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if strings.HasPrefix(auth, "Bearer ") {
|
|
|
|
auth = auth[len("Bearer "):]
|
|
|
|
}
|
2022-10-21 22:04:21 +00:00
|
|
|
if auth != prov.bridge.Config.Bridge.Provisioning.SharedSecret {
|
2020-02-09 18:32:14 +00:00
|
|
|
jsonResponse(w, http.StatusForbidden, map[string]interface{}{
|
|
|
|
"error": "Invalid auth token",
|
|
|
|
"errcode": "M_FORBIDDEN",
|
|
|
|
})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
userID := r.URL.Query().Get("user_id")
|
2020-05-08 19:32:22 +00:00
|
|
|
user := prov.bridge.GetUserByMXID(id.UserID(userID))
|
2020-02-09 18:32:14 +00:00
|
|
|
h.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), "user", user)))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
type Error struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
Error string `json:"error"`
|
|
|
|
ErrCode string `json:"errcode"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Response struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
Status string `json:"status"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func jsonResponse(w http.ResponseWriter, status int, response interface{}) {
|
|
|
|
w.Header().Add("Content-Type", "application/json")
|
|
|
|
w.WriteHeader(status)
|
|
|
|
_ = json.NewEncoder(w).Encode(response)
|
|
|
|
}
|