groupme/provisioning.go

85 lines
2.7 KiB
Go
Raw Normal View History

// 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 {
bridge *GMBridge
2020-02-09 18:32:14 +00:00
log log.Logger
}
func (prov *ProvisioningAPI) Init() {
prov.log = prov.bridge.Log.Sub("Provisioning")
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")
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)
if strings.HasPrefix(part, "com.beeper.groupme.auth-") {
auth = part[len("com.beeper.groupme.auth-"):]
break
}
}
} else if strings.HasPrefix(auth, "Bearer ") {
auth = auth[len("Bearer "):]
}
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)
}