Move MakeJoin logic to GMSL (#3081)

This commit is contained in:
devonh 2023-05-17 00:33:27 +00:00 committed by GitHub
parent 0489d16f95
commit 67d6876857
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
80 changed files with 1158 additions and 494 deletions

View file

@ -98,7 +98,10 @@ func Backfill(
// Query the roomserver.
if err = rsAPI.PerformBackfill(httpReq.Context(), &req, &res); err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("query.PerformBackfill failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
// Filter any event that's not from the requested room out.

View file

@ -38,7 +38,10 @@ func GetUserDevices(
}
if res.Error != nil {
util.GetLogger(req.Context()).WithError(res.Error).Error("keyAPI.QueryDeviceMessages failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
sigReq := &api.QuerySignaturesRequest{

View file

@ -183,7 +183,10 @@ func processInvite(
verifyResults, err := keys.VerifyJSONs(ctx, verifyRequests)
if err != nil {
util.GetLogger(ctx).WithError(err).Error("keys.VerifyJSONs failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
if verifyResults[0].Error != nil {
return util.JSONResponse{
@ -211,7 +214,7 @@ func processInvite(
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError(),
JSON: spec.InternalServerError{},
}
}
@ -232,7 +235,7 @@ func processInvite(
sentry.CaptureException(err)
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError(),
JSON: spec.InternalServerError{},
}
}

View file

@ -15,6 +15,7 @@
package routing
import (
"context"
"encoding/json"
"fmt"
"net/http"
@ -33,153 +34,187 @@ import (
"github.com/matrix-org/dendrite/setup/config"
)
type JoinRoomQuerier struct {
roomserver api.FederationRoomserverAPI
}
func (rq *JoinRoomQuerier) CurrentStateEvent(ctx context.Context, roomID spec.RoomID, eventType string, stateKey string) (gomatrixserverlib.PDU, error) {
return rq.roomserver.CurrentStateEvent(ctx, roomID, eventType, stateKey)
}
func (rq *JoinRoomQuerier) InvitePending(ctx context.Context, roomID spec.RoomID, userID spec.UserID) (bool, error) {
return rq.roomserver.InvitePending(ctx, roomID, userID)
}
func (rq *JoinRoomQuerier) RestrictedRoomJoinInfo(ctx context.Context, roomID spec.RoomID, userID spec.UserID, localServerName spec.ServerName) (*gomatrixserverlib.RestrictedRoomJoinInfo, error) {
roomInfo, err := rq.roomserver.QueryRoomInfo(ctx, roomID)
if err != nil || roomInfo == nil || roomInfo.IsStub() {
return nil, err
}
req := api.QueryServerJoinedToRoomRequest{
ServerName: localServerName,
RoomID: roomID.String(),
}
res := api.QueryServerJoinedToRoomResponse{}
if err = rq.roomserver.QueryServerJoinedToRoom(ctx, &req, &res); err != nil {
util.GetLogger(ctx).WithError(err).Error("rsAPI.QueryServerJoinedToRoom failed")
return nil, fmt.Errorf("InternalServerError: Failed to query room: %w", err)
}
userJoinedToRoom, err := rq.roomserver.UserJoinedToRoom(ctx, types.RoomNID(roomInfo.RoomNID), userID)
if err != nil {
util.GetLogger(ctx).WithError(err).Error("rsAPI.UserJoinedToRoom failed")
return nil, fmt.Errorf("InternalServerError: %w", err)
}
locallyJoinedUsers, err := rq.roomserver.LocallyJoinedUsers(ctx, roomInfo.RoomVersion, types.RoomNID(roomInfo.RoomNID))
if err != nil {
util.GetLogger(ctx).WithError(err).Error("rsAPI.GetLocallyJoinedUsers failed")
return nil, fmt.Errorf("InternalServerError: %w", err)
}
return &gomatrixserverlib.RestrictedRoomJoinInfo{
LocalServerInRoom: res.RoomExists && res.IsInRoom,
UserJoinedToRoom: userJoinedToRoom,
JoinedUsers: locallyJoinedUsers,
}, nil
}
// MakeJoin implements the /make_join API
func MakeJoin(
httpReq *http.Request,
request *fclient.FederationRequest,
cfg *config.FederationAPI,
rsAPI api.FederationRoomserverAPI,
roomID, userID string,
roomID spec.RoomID, userID spec.UserID,
remoteVersions []gomatrixserverlib.RoomVersion,
) util.JSONResponse {
roomVersion, err := rsAPI.QueryRoomVersionForRoom(httpReq.Context(), roomID)
roomVersion, err := rsAPI.QueryRoomVersionForRoom(httpReq.Context(), roomID.String())
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("failed obtaining room version")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError(),
JSON: spec.InternalServerError{},
}
}
// Check that the room that the remote side is trying to join is actually
// one of the room versions that they listed in their supported ?ver= in
// the make_join URL.
// https://matrix.org/docs/spec/server_server/r0.1.3#get-matrix-federation-v1-make-join-roomid-userid
remoteSupportsVersion := false
for _, v := range remoteVersions {
if v == roomVersion {
remoteSupportsVersion = true
break
}
}
// If it isn't, stop trying to join the room.
if !remoteSupportsVersion {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.IncompatibleRoomVersion(string(roomVersion)),
}
}
_, domain, err := gomatrixserverlib.SplitID('@', userID)
if err != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.BadJSON("Invalid UserID"),
}
}
if domain != request.Origin() {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: spec.Forbidden("The join must be sent by the server of the user"),
}
}
// Check if we think we are still joined to the room
inRoomReq := &api.QueryServerJoinedToRoomRequest{
req := api.QueryServerJoinedToRoomRequest{
ServerName: cfg.Matrix.ServerName,
RoomID: roomID,
RoomID: roomID.String(),
}
inRoomRes := &api.QueryServerJoinedToRoomResponse{}
if err = rsAPI.QueryServerJoinedToRoom(httpReq.Context(), inRoomReq, inRoomRes); err != nil {
res := api.QueryServerJoinedToRoomResponse{}
if err := rsAPI.QueryServerJoinedToRoom(httpReq.Context(), &req, &res); err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("rsAPI.QueryServerJoinedToRoom failed")
return spec.InternalServerError()
}
if !inRoomRes.RoomExists {
return util.JSONResponse{
Code: http.StatusNotFound,
JSON: spec.NotFound(fmt.Sprintf("Room ID %q was not found on this server", roomID)),
}
}
if !inRoomRes.IsInRoom {
return util.JSONResponse{
Code: http.StatusNotFound,
JSON: spec.NotFound(fmt.Sprintf("Room ID %q has no remaining users on this server", roomID)),
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
// Check if the restricted join is allowed. If the room doesn't
// support restricted joins then this is effectively a no-op.
res, authorisedVia, err := checkRestrictedJoin(httpReq, rsAPI, roomVersion, roomID, userID)
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("checkRestrictedJoin failed")
return spec.InternalServerError()
} else if res != nil {
return *res
createJoinTemplate := func(proto *gomatrixserverlib.ProtoEvent) (gomatrixserverlib.PDU, []gomatrixserverlib.PDU, error) {
identity, err := cfg.Matrix.SigningIdentityFor(request.Destination())
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Errorf("obtaining signing identity for %s failed", request.Destination())
return nil, nil, spec.NotFound(fmt.Sprintf("Server name %q does not exist", request.Destination()))
}
queryRes := api.QueryLatestEventsAndStateResponse{
RoomVersion: roomVersion,
}
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), proto, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
switch e := err.(type) {
case nil:
case eventutil.ErrRoomNoExists:
util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
return nil, nil, spec.NotFound("Room does not exist")
case gomatrixserverlib.BadJSONError:
util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
return nil, nil, spec.BadJSON(e.Error())
default:
util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
return nil, nil, spec.InternalServerError{}
}
stateEvents := make([]gomatrixserverlib.PDU, len(queryRes.StateEvents))
for i, stateEvent := range queryRes.StateEvents {
stateEvents[i] = stateEvent.PDU
}
return event, stateEvents, nil
}
// Try building an event for the server
proto := gomatrixserverlib.ProtoEvent{
Sender: userID,
RoomID: roomID,
Type: "m.room.member",
StateKey: &userID,
}
content := gomatrixserverlib.MemberContent{
Membership: spec.Join,
AuthorisedVia: authorisedVia,
}
if err = proto.SetContent(content); err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("builder.SetContent failed")
return spec.InternalServerError()
roomQuerier := JoinRoomQuerier{
roomserver: rsAPI,
}
identity, err := cfg.Matrix.SigningIdentityFor(request.Destination())
if err != nil {
return util.JSONResponse{
Code: http.StatusNotFound,
JSON: spec.NotFound(
fmt.Sprintf("Server name %q does not exist", request.Destination()),
),
input := gomatrixserverlib.HandleMakeJoinInput{
Context: httpReq.Context(),
UserID: userID,
RoomID: roomID,
RoomVersion: roomVersion,
RemoteVersions: remoteVersions,
RequestOrigin: request.Origin(),
LocalServerName: cfg.Matrix.ServerName,
LocalServerInRoom: res.RoomExists && res.IsInRoom,
RoomQuerier: &roomQuerier,
BuildEventTemplate: createJoinTemplate,
}
response, internalErr := gomatrixserverlib.HandleMakeJoin(input)
if internalErr != nil {
switch e := internalErr.(type) {
case nil:
case spec.InternalServerError:
util.GetLogger(httpReq.Context()).WithError(internalErr)
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
case spec.MatrixError:
util.GetLogger(httpReq.Context()).WithError(internalErr)
code := http.StatusInternalServerError
switch e.ErrCode {
case spec.ErrorForbidden:
code = http.StatusForbidden
case spec.ErrorNotFound:
code = http.StatusNotFound
case spec.ErrorUnableToAuthoriseJoin:
code = http.StatusBadRequest
case spec.ErrorBadJSON:
code = http.StatusBadRequest
}
return util.JSONResponse{
Code: code,
JSON: e,
}
case spec.IncompatibleRoomVersionError:
util.GetLogger(httpReq.Context()).WithError(internalErr)
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: e,
}
default:
util.GetLogger(httpReq.Context()).WithError(internalErr)
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.Unknown("unknown error"),
}
}
}
queryRes := api.QueryLatestEventsAndStateResponse{
RoomVersion: roomVersion,
}
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), &proto, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
if response == nil {
util.GetLogger(httpReq.Context()).Error("gmsl.HandleMakeJoin returned invalid response")
return util.JSONResponse{
Code: http.StatusNotFound,
JSON: spec.NotFound("Room does not exist"),
}
} else if e, ok := err.(gomatrixserverlib.BadJSONError); ok {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.BadJSON(e.Error()),
}
} else if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
return spec.InternalServerError()
}
// Check that the join is allowed or not
stateEvents := make([]gomatrixserverlib.PDU, len(queryRes.StateEvents))
for i := range queryRes.StateEvents {
stateEvents[i] = queryRes.StateEvents[i].PDU
}
provider := gomatrixserverlib.NewAuthEvents(stateEvents)
if err = gomatrixserverlib.Allowed(event.PDU, &provider); err != nil {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: spec.Forbidden(err.Error()),
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
return util.JSONResponse{
Code: http.StatusOK,
JSON: map[string]interface{}{
"event": proto,
"room_version": roomVersion,
"event": response.JoinTemplateEvent,
"room_version": response.RoomVersion,
},
}
}
@ -201,7 +236,7 @@ func SendJoin(
util.GetLogger(httpReq.Context()).WithError(err).Error("rsAPI.QueryRoomVersionForRoom failed")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError(),
JSON: spec.InternalServerError{},
}
}
verImpl, err := gomatrixserverlib.GetRoomVersion(roomVersion)
@ -311,7 +346,10 @@ func SendJoin(
verifyResults, err := keys.VerifyJSONs(httpReq.Context(), verifyRequests)
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("keys.VerifyJSONs failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
if verifyResults[0].Error != nil {
return util.JSONResponse{
@ -331,7 +369,10 @@ func SendJoin(
}, &stateAndAuthChainResponse)
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("rsAPI.QueryStateAndAuthChain failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
if !stateAndAuthChainResponse.RoomExists {
@ -427,7 +468,10 @@ func SendJoin(
JSON: spec.Forbidden(response.ErrMsg),
}
}
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
}
@ -449,74 +493,6 @@ func SendJoin(
}
}
// checkRestrictedJoin finds out whether or not we can assist in processing
// a restricted room join. If the room version does not support restricted
// joins then this function returns with no side effects. This returns three
// values:
// - an optional JSON response body (i.e. M_UNABLE_TO_AUTHORISE_JOIN) which
// should always be sent back to the client if one is specified
// - a user ID of an authorising user, typically a user that has power to
// issue invites in the room, if one has been found
// - an error if there was a problem finding out if this was allowable,
// like if the room version isn't known or a problem happened talking to
// the roomserver
func checkRestrictedJoin(
httpReq *http.Request,
rsAPI api.FederationRoomserverAPI,
roomVersion gomatrixserverlib.RoomVersion,
roomID, userID string,
) (*util.JSONResponse, string, error) {
verImpl, err := gomatrixserverlib.GetRoomVersion(roomVersion)
if err != nil {
return nil, "", err
}
if !verImpl.MayAllowRestrictedJoinsInEventAuth() {
return nil, "", nil
}
req := &api.QueryRestrictedJoinAllowedRequest{
RoomID: roomID,
UserID: userID,
}
res := &api.QueryRestrictedJoinAllowedResponse{}
if err := rsAPI.QueryRestrictedJoinAllowed(httpReq.Context(), req, res); err != nil {
return nil, "", err
}
switch {
case !res.Restricted:
// The join rules for the room don't restrict membership.
return nil, "", nil
case !res.Resident:
// The join rules restrict membership but our server isn't currently
// joined to all of the allowed rooms, so we can't actually decide
// whether or not to allow the user to join. This error code should
// tell the joining server to try joining via another resident server
// instead.
return &util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.UnableToAuthoriseJoin("This server cannot authorise the join."),
}, "", nil
case !res.Allowed:
// The join rules restrict membership, our server is in the relevant
// rooms and the user wasn't joined to join any of the allowed rooms
// and therefore can't join this room.
return &util.JSONResponse{
Code: http.StatusForbidden,
JSON: spec.Forbidden("You are not joined to any matching rooms."),
}, "", nil
default:
// The join rules restrict membership, our server is in the relevant
// rooms and the user was allowed to join because they belong to one
// of the allowed rooms. We now need to pick one of our own local users
// from within the room to use as the authorising user ID, so that it
// can be referred to from within the membership content.
return nil, res.AuthorisedVia, nil
}
}
type eventsByDepth []*types.HeaderedEvent
func (e eventsByDepth) Len() int {

View file

@ -67,7 +67,10 @@ func QueryDeviceKeys(
}, &queryRes)
if queryRes.Error != nil {
util.GetLogger(httpReq.Context()).WithError(queryRes.Error).Error("Failed to QueryKeys")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
return util.JSONResponse{
Code: 200,
@ -119,7 +122,10 @@ func ClaimOneTimeKeys(
}, &claimRes)
if claimRes.Error != nil {
util.GetLogger(httpReq.Context()).WithError(claimRes.Error).Error("Failed to PerformClaimKeys")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
return util.JSONResponse{
Code: 200,
@ -243,7 +249,10 @@ func NotaryKeys(
j, err := json.Marshal(keys)
if err != nil {
logrus.WithError(err).Errorf("Failed to marshal %q response", serverName)
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
js, err := gomatrixserverlib.SignJSON(
@ -251,7 +260,10 @@ func NotaryKeys(
)
if err != nil {
logrus.WithError(err).Errorf("Failed to sign %q response", serverName)
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
response.ServerKeys = append(response.ServerKeys, js)

View file

@ -60,7 +60,10 @@ func MakeLeave(
err = proto.SetContent(map[string]interface{}{"membership": spec.Leave})
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("proto.SetContent failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
identity, err := cfg.Matrix.SigningIdentityFor(request.Destination())
@ -75,19 +78,26 @@ func MakeLeave(
var queryRes api.QueryLatestEventsAndStateResponse
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), &proto, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
switch e := err.(type) {
case nil:
case eventutil.ErrRoomNoExists:
util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
return util.JSONResponse{
Code: http.StatusNotFound,
JSON: spec.NotFound("Room does not exist"),
}
} else if e, ok := err.(gomatrixserverlib.BadJSONError); ok {
case gomatrixserverlib.BadJSONError:
util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.BadJSON(e.Error()),
}
} else if err != nil {
default:
util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
// If the user has already left then just return their last leave
@ -233,7 +243,10 @@ func SendLeave(
err = rsAPI.QueryLatestEventsAndState(httpReq.Context(), queryReq, queryRes)
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("rsAPI.QueryLatestEventsAndState failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
// The room doesn't exist or we weren't ever joined to it. Might as well
// no-op here.
@ -279,7 +292,10 @@ func SendLeave(
verifyResults, err := keys.VerifyJSONs(httpReq.Context(), verifyRequests)
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("keys.VerifyJSONs failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
if verifyResults[0].Error != nil {
return util.JSONResponse{
@ -327,7 +343,10 @@ func SendLeave(
JSON: spec.Forbidden(response.ErrMsg),
}
}
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
return util.JSONResponse{

View file

@ -63,7 +63,10 @@ func GetMissingEvents(
&eventsResponse,
); err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("query.QueryMissingEvents failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
eventsResponse.Events = filterEvents(eventsResponse.Events, roomID)

View file

@ -40,7 +40,7 @@ func Peek(
if err != nil {
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError(),
JSON: spec.InternalServerError{},
}
}

View file

@ -53,7 +53,10 @@ func GetProfile(
profile, err := userAPI.QueryProfile(httpReq.Context(), userID)
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("userAPI.QueryProfile failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
var res interface{}

View file

@ -39,7 +39,10 @@ func GetPostPublicRooms(req *http.Request, rsAPI roomserverAPI.FederationRoomser
}
response, err := publicRooms(req.Context(), request, rsAPI)
if err != nil {
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
return util.JSONResponse{
Code: http.StatusOK,
@ -106,8 +109,10 @@ func fillPublicRoomsReq(httpReq *http.Request, request *PublicRoomReq) *util.JSO
// In that case, we want to assign 0 so we ignore the error
if err != nil && len(httpReq.FormValue("limit")) > 0 {
util.GetLogger(httpReq.Context()).WithError(err).Error("strconv.Atoi failed")
reqErr := spec.InternalServerError()
return &reqErr
return &util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
request.Limit = int16(limit)
request.Since = httpReq.FormValue("since")

View file

@ -61,7 +61,10 @@ func RoomAliasToID(
queryRes := &roomserverAPI.GetRoomIDForAliasResponse{}
if err = rsAPI.GetRoomIDForAlias(httpReq.Context(), queryReq, queryRes); err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("aliasAPI.GetRoomIDForAlias failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
if queryRes.RoomID != "" {
@ -69,7 +72,10 @@ func RoomAliasToID(
var serverQueryRes federationAPI.QueryJoinedHostServerNamesInRoomResponse
if err = senderAPI.QueryJoinedHostServerNamesInRoom(httpReq.Context(), &serverQueryReq, &serverQueryRes); err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("senderAPI.QueryJoinedHostServerNamesInRoom failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
resp = fclient.RespDirectory{
@ -98,7 +104,10 @@ func RoomAliasToID(
// TODO: Return 502 if the remote server errored.
// TODO: Return 504 if the remote server timed out.
util.GetLogger(httpReq.Context()).WithError(err).Error("federation.LookupRoomAlias failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
}

View file

@ -312,8 +312,6 @@ func Setup(
JSON: spec.Forbidden("Forbidden by server ACLs"),
}
}
roomID := vars["roomID"]
userID := vars["userID"]
queryVars := httpReq.URL.Query()
remoteVersions := []gomatrixserverlib.RoomVersion{}
if vers, ok := queryVars["ver"]; ok {
@ -328,8 +326,25 @@ func Setup(
// https://matrix.org/docs/spec/server_server/r0.1.3#get-matrix-federation-v1-make-join-roomid-userid
remoteVersions = append(remoteVersions, gomatrixserverlib.RoomVersionV1)
}
userID, err := spec.NewUserID(vars["userID"], true)
if err != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.BadJSON("Invalid UserID"),
}
}
roomID, err := spec.NewRoomID(vars["roomID"])
if err != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.BadJSON("Invalid RoomID"),
}
}
logrus.Debugf("Processing make_join for user %s, room %s", userID.String(), roomID.String())
return MakeJoin(
httpReq, request, cfg, rsAPI, roomID, userID, remoteVersions,
httpReq, request, cfg, rsAPI, *roomID, *userID, remoteVersions,
)
},
)).Methods(http.MethodGet)
@ -353,7 +368,7 @@ func Setup(
body = []interface{}{
res.Code, res.JSON,
}
jerr, ok := res.JSON.(*spec.MatrixError)
jerr, ok := res.JSON.(spec.MatrixError)
if ok {
body = jerr
}
@ -419,7 +434,7 @@ func Setup(
body = []interface{}{
res.Code, res.JSON,
}
jerr, ok := res.JSON.(*spec.MatrixError)
jerr, ok := res.JSON.(spec.MatrixError)
if ok {
body = jerr
}
@ -566,7 +581,7 @@ func MakeFedAPI(
go wakeup.Wakeup(req.Context(), fedReq.Origin())
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil {
return util.MatrixErrorResponse(400, "M_UNRECOGNISED", "badly encoded query params")
return util.MatrixErrorResponse(400, string(spec.ErrorUnrecognized), "badly encoded query params")
}
jsonRes := f(req, fedReq, vars)

View file

@ -80,7 +80,10 @@ func CreateInvitesFrom3PIDInvites(
)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("createInviteFrom3PIDInvite failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
if event != nil {
evs = append(evs, &types.HeaderedEvent{PDU: event})
@ -100,7 +103,10 @@ func CreateInvitesFrom3PIDInvites(
false,
); err != nil {
util.GetLogger(req.Context()).WithError(err).Error("SendEvents failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
return util.JSONResponse{
@ -176,7 +182,10 @@ func ExchangeThirdPartyInvite(
}
} else if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("buildMembershipEvent failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
// Ask the requesting server to sign the newly created event so we know it
@ -184,22 +193,34 @@ func ExchangeThirdPartyInvite(
inviteReq, err := fclient.NewInviteV2Request(event, nil)
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("failed to make invite v2 request")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
signedEvent, err := federation.SendInviteV2(httpReq.Context(), senderDomain, request.Origin(), inviteReq)
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("federation.SendInvite failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
verImpl, err := gomatrixserverlib.GetRoomVersion(roomVersion)
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Errorf("unknown room version: %s", roomVersion)
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
inviteEvent, err := verImpl.NewEventFromUntrustedJSON(signedEvent.Event)
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("federation.SendInvite failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
// Send the event to the roomserver
@ -216,7 +237,10 @@ func ExchangeThirdPartyInvite(
false,
); err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("SendEvents failed")
return spec.InternalServerError()
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
return util.JSONResponse{