aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--federationapi/routing/join.go10
-rw-r--r--federationapi/routing/leave.go145
-rw-r--r--federationapi/routing/routing.go20
-rw-r--r--go.mod2
-rw-r--r--go.sum4
5 files changed, 100 insertions, 81 deletions
diff --git a/federationapi/routing/join.go b/federationapi/routing/join.go
index cbdeca51..4cbfc5e8 100644
--- a/federationapi/routing/join.go
+++ b/federationapi/routing/join.go
@@ -99,7 +99,7 @@ func MakeJoin(
}
req := api.QueryServerJoinedToRoomRequest{
- ServerName: cfg.Matrix.ServerName,
+ ServerName: request.Destination(),
RoomID: roomID.String(),
}
res := api.QueryServerJoinedToRoomResponse{}
@@ -162,13 +162,13 @@ func MakeJoin(
switch e := internalErr.(type) {
case nil:
case spec.InternalServerError:
- util.GetLogger(httpReq.Context()).WithError(internalErr)
+ util.GetLogger(httpReq.Context()).WithError(internalErr).Error("failed to handle make_join request")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
case spec.MatrixError:
- util.GetLogger(httpReq.Context()).WithError(internalErr)
+ util.GetLogger(httpReq.Context()).WithError(internalErr).Error("failed to handle make_join request")
code := http.StatusInternalServerError
switch e.ErrCode {
case spec.ErrorForbidden:
@@ -186,13 +186,13 @@ func MakeJoin(
JSON: e,
}
case spec.IncompatibleRoomVersionError:
- util.GetLogger(httpReq.Context()).WithError(internalErr)
+ util.GetLogger(httpReq.Context()).WithError(internalErr).Error("failed to handle make_join request")
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: e,
}
default:
- util.GetLogger(httpReq.Context()).WithError(internalErr)
+ util.GetLogger(httpReq.Context()).WithError(internalErr).Error("failed to handle make_join request")
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.Unknown("unknown error"),
diff --git a/federationapi/routing/leave.go b/federationapi/routing/leave.go
index e6540340..3e576e09 100644
--- a/federationapi/routing/leave.go
+++ b/federationapi/routing/leave.go
@@ -34,108 +34,115 @@ func MakeLeave(
request *fclient.FederationRequest,
cfg *config.FederationAPI,
rsAPI api.FederationRoomserverAPI,
- roomID, userID string,
+ roomID spec.RoomID, userID spec.UserID,
) util.JSONResponse {
- _, domain, err := gomatrixserverlib.SplitID('@', userID)
+ 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.StatusBadRequest,
- JSON: spec.BadJSON("Invalid UserID"),
- }
- }
- if domain != request.Origin() {
- return util.JSONResponse{
- Code: http.StatusForbidden,
- JSON: spec.Forbidden("The leave must be sent by the server of the user"),
+ Code: http.StatusInternalServerError,
+ JSON: spec.InternalServerError{},
}
}
- // Try building an event for the server
- proto := gomatrixserverlib.ProtoEvent{
- Sender: userID,
- RoomID: roomID,
- Type: "m.room.member",
- StateKey: &userID,
+ req := api.QueryServerJoinedToRoomRequest{
+ ServerName: request.Destination(),
+ RoomID: roomID.String(),
}
- err = proto.SetContent(map[string]interface{}{"membership": spec.Leave})
- if err != nil {
- util.GetLogger(httpReq.Context()).WithError(err).Error("proto.SetContent failed")
+ res := api.QueryServerJoinedToRoomResponse{}
+ if err := rsAPI.QueryServerJoinedToRoom(httpReq.Context(), &req, &res); err != nil {
+ util.GetLogger(httpReq.Context()).WithError(err).Error("rsAPI.QueryServerJoinedToRoom failed")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
- 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()),
- ),
+ createLeaveTemplate := 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()))
}
- }
- var queryRes api.QueryLatestEventsAndStateResponse
- 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 util.JSONResponse{
- Code: http.StatusNotFound,
- JSON: spec.NotFound("Room does not exist"),
+ queryRes := api.QueryLatestEventsAndStateResponse{}
+ 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{}
}
- case gomatrixserverlib.BadJSONError:
- util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
- return util.JSONResponse{
- Code: http.StatusBadRequest,
- JSON: spec.BadJSON(e.Error()),
+
+ stateEvents := make([]gomatrixserverlib.PDU, len(queryRes.StateEvents))
+ for i, stateEvent := range queryRes.StateEvents {
+ stateEvents[i] = stateEvent.PDU
}
- default:
- util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
+ return event, stateEvents, nil
+ }
+
+ input := gomatrixserverlib.HandleMakeLeaveInput{
+ UserID: userID,
+ RoomID: roomID,
+ RoomVersion: roomVersion,
+ RequestOrigin: request.Origin(),
+ LocalServerName: cfg.Matrix.ServerName,
+ LocalServerInRoom: res.RoomExists && res.IsInRoom,
+ BuildEventTemplate: createLeaveTemplate,
+ }
+
+ response, internalErr := gomatrixserverlib.HandleMakeLeave(input)
+ switch e := internalErr.(type) {
+ case nil:
+ case spec.InternalServerError:
+ util.GetLogger(httpReq.Context()).WithError(internalErr).Error("failed to handle make_leave request")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
- }
+ case spec.MatrixError:
+ util.GetLogger(httpReq.Context()).WithError(internalErr).Error("failed to handle make_leave request")
+ code := http.StatusInternalServerError
+ switch e.ErrCode {
+ case spec.ErrorForbidden:
+ code = http.StatusForbidden
+ case spec.ErrorNotFound:
+ code = http.StatusNotFound
+ case spec.ErrorBadJSON:
+ code = http.StatusBadRequest
+ }
- // If the user has already left then just return their last leave
- // event. This means that /send_leave will be a no-op, which helps
- // to reject invites multiple times - hopefully.
- for _, state := range queryRes.StateEvents {
- if !state.StateKeyEquals(userID) {
- continue
+ return util.JSONResponse{
+ Code: code,
+ JSON: e,
}
- if mem, merr := state.Membership(); merr == nil && mem == spec.Leave {
- return util.JSONResponse{
- Code: http.StatusOK,
- JSON: map[string]interface{}{
- "room_version": event.Version(),
- "event": state,
- },
- }
+ default:
+ util.GetLogger(httpReq.Context()).WithError(internalErr).Error("failed to handle make_leave request")
+ return util.JSONResponse{
+ Code: http.StatusBadRequest,
+ JSON: spec.Unknown("unknown error"),
}
}
- // Check that the leave 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, &provider); err != nil {
+ if response == nil {
+ util.GetLogger(httpReq.Context()).Error("gmsl.HandleMakeLeave returned invalid response")
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{}{
- "room_version": event.Version(),
- "event": proto,
+ "event": response.LeaveTemplateEvent,
+ "room_version": response.RoomVersion,
},
}
}
diff --git a/federationapi/routing/routing.go b/federationapi/routing/routing.go
index 7be0857a..fad06c1c 100644
--- a/federationapi/routing/routing.go
+++ b/federationapi/routing/routing.go
@@ -412,7 +412,7 @@ func Setup(
},
)).Methods(http.MethodPut)
- v1fedmux.Handle("/make_leave/{roomID}/{eventID}", MakeFedAPI(
+ v1fedmux.Handle("/make_leave/{roomID}/{userID}", MakeFedAPI(
"federation_make_leave", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
func(httpReq *http.Request, request *fclient.FederationRequest, vars map[string]string) util.JSONResponse {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
@@ -421,10 +421,22 @@ func Setup(
JSON: spec.Forbidden("Forbidden by server ACLs"),
}
}
- roomID := vars["roomID"]
- eventID := vars["eventID"]
+ roomID, err := spec.NewRoomID(vars["roomID"])
+ if err != nil {
+ return util.JSONResponse{
+ Code: http.StatusBadRequest,
+ JSON: spec.InvalidParam("Invalid RoomID"),
+ }
+ }
+ userID, err := spec.NewUserID(vars["userID"], true)
+ if err != nil {
+ return util.JSONResponse{
+ Code: http.StatusBadRequest,
+ JSON: spec.InvalidParam("Invalid UserID"),
+ }
+ }
return MakeLeave(
- httpReq, request, cfg, rsAPI, roomID, eventID,
+ httpReq, request, cfg, rsAPI, *roomID, *userID,
)
},
)).Methods(http.MethodGet)
diff --git a/go.mod b/go.mod
index e8505177..bf2dc5de 100644
--- a/go.mod
+++ b/go.mod
@@ -22,7 +22,7 @@ require (
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530
- github.com/matrix-org/gomatrixserverlib v0.0.0-20230519160810-b92e84b02a7c
+ github.com/matrix-org/gomatrixserverlib v0.0.0-20230523164045-3fddabebb511
github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66
github.com/mattn/go-sqlite3 v1.14.16
diff --git a/go.sum b/go.sum
index 6f034fef..574a7bd7 100644
--- a/go.sum
+++ b/go.sum
@@ -323,8 +323,8 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91 h1:s7fexw
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91/go.mod h1:e+cg2q7C7yE5QnAXgzo512tgFh1RbQLC0+jozuegKgo=
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 h1:kHKxCOLcHH8r4Fzarl4+Y3K5hjothkVW5z7T1dUM11U=
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
-github.com/matrix-org/gomatrixserverlib v0.0.0-20230519160810-b92e84b02a7c h1:EF04pmshcDmBQOrBQbzT5htyTivetfyvR70gX2hB9AM=
-github.com/matrix-org/gomatrixserverlib v0.0.0-20230519160810-b92e84b02a7c/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU=
+github.com/matrix-org/gomatrixserverlib v0.0.0-20230523164045-3fddabebb511 h1:om6z/WEVZMxZfgtiyfp5r5ubAObGMyRrnlVD07gIRY4=
+github.com/matrix-org/gomatrixserverlib v0.0.0-20230523164045-3fddabebb511/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU=
github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a h1:awrPDf9LEFySxTLKYBMCiObelNx/cBuv/wzllvCCH3A=
github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a/go.mod h1:HchJX9oKMXaT2xYFs0Ha/6Zs06mxLU8k6F1ODnrGkeQ=
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 h1:6z4KxomXSIGWqhHcfzExgkH3Z3UkIXry4ibJS4Aqz2Y=