diff options
author | Neil Alexander <neilalexander@users.noreply.github.com> | 2020-05-04 13:53:47 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-04 13:53:47 +0100 |
commit | 5c894efd0ee67bf911b9c3b5428a61ddc58819de (patch) | |
tree | 3b576827ad15d26eaa09423492231c00893dec54 /federationapi | |
parent | 36bbb255614d289a3417194d4d2ac129e339f531 (diff) |
Roomserver perform join (#1001)
* Add PerformJoin template
* Try roomserver perform join
* Send correct server name to FS API
* Pass through content, try to handle multiple server names
* Fix local server checks
* Don't refer to non-existent error
* Add directory lookups of aliases
* Remove unneeded parameters
* Don't repeat join events into the roomserver
* Unmarshal the content, that would help
* Check if the user is already in the room in the fedeationapi too
* Return incompatible room version error
* Use Membership, don't try more servers than needed
* Review comments, make FS API take list of servernames, dedupe them, break out of loop properly on success
* Tweaks
Diffstat (limited to 'federationapi')
-rw-r--r-- | federationapi/routing/join.go | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/federationapi/routing/join.go b/federationapi/routing/join.go index be5e988a..6cadbd75 100644 --- a/federationapi/routing/join.go +++ b/federationapi/routing/join.go @@ -61,9 +61,7 @@ func MakeJoin( if !remoteSupportsVersion { return util.JSONResponse{ Code: http.StatusBadRequest, - JSON: jsonerror.UnsupportedRoomVersion( - fmt.Sprintf("Joining server does not support room version %s", verRes.RoomVersion), - ), + JSON: jsonerror.IncompatibleRoomVersion(verRes.RoomVersion), } } @@ -132,6 +130,9 @@ func MakeJoin( } // SendJoin implements the /send_join API +// The make-join send-join dance makes much more sense as a single +// flow so the cyclomatic complexity is high: +// nolint:gocyclo func SendJoin( httpReq *http.Request, request *gomatrixserverlib.FederationRequest, @@ -159,6 +160,16 @@ func SendJoin( } } + // Check that a state key is provided. + if event.StateKey() == nil || (event.StateKey() != nil && *event.StateKey() == "") { + return util.JSONResponse{ + Code: http.StatusBadRequest, + JSON: jsonerror.BadJSON( + fmt.Sprintf("No state key was provided in the join event."), + ), + } + } + // Check that the room ID is correct. if event.RoomID() != roomID { return util.JSONResponse{ @@ -234,20 +245,34 @@ func SendJoin( } } + // Check if the user is already in the room. If they're already in then + // there isn't much point in sending another join event into the room. + alreadyJoined := false + for _, se := range stateAndAuthChainResponse.StateEvents { + if membership, merr := se.Membership(); merr == nil { + if se.StateKey() != nil && *se.StateKey() == *event.StateKey() { + alreadyJoined = (membership == "join") + break + } + } + } + // Send the events to the room server. // We are responsible for notifying other servers that the user has joined // the room, so set SendAsServer to cfg.Matrix.ServerName - _, err = producer.SendEvents( - httpReq.Context(), - []gomatrixserverlib.HeaderedEvent{ - event.Headered(stateAndAuthChainResponse.RoomVersion), - }, - cfg.Matrix.ServerName, - nil, - ) - if err != nil { - util.GetLogger(httpReq.Context()).WithError(err).Error("producer.SendEvents failed") - return jsonerror.InternalServerError() + if !alreadyJoined { + _, err = producer.SendEvents( + httpReq.Context(), + []gomatrixserverlib.HeaderedEvent{ + event.Headered(stateAndAuthChainResponse.RoomVersion), + }, + cfg.Matrix.ServerName, + nil, + ) + if err != nil { + util.GetLogger(httpReq.Context()).WithError(err).Error("producer.SendEvents failed") + return jsonerror.InternalServerError() + } } return util.JSONResponse{ |