aboutsummaryrefslogtreecommitdiff
path: root/federationapi
diff options
context:
space:
mode:
authorNeil Alexander <neilalexander@users.noreply.github.com>2020-05-04 13:53:47 +0100
committerGitHub <noreply@github.com>2020-05-04 13:53:47 +0100
commit5c894efd0ee67bf911b9c3b5428a61ddc58819de (patch)
tree3b576827ad15d26eaa09423492231c00893dec54 /federationapi
parent36bbb255614d289a3417194d4d2ac129e339f531 (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.go53
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{