diff options
author | Neil Alexander <neilalexander@users.noreply.github.com> | 2022-05-25 10:05:30 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-25 10:05:30 +0100 |
commit | 81843e8836e6f8f334c7b5fd1433c427c10a9443 (patch) | |
tree | da86bc862d46103b955431961df95fab90c199b6 /federationapi/internal | |
parent | d621dd2986fa0b8cce9d164a7249456d0be47c81 (diff) |
Restricted join support on `/make_join`, `/send_join` (#2478)
* Add `QueryRestrictedJoinAllowed`
* Add `Resident` flag to `QueryRestrictedJoinAllowedResponse`
* Check restricted joins on federation API
* Return `Restricted` to determine if the room was restricted or not
* Populate `AuthorisedVia` properly
* Sign the event on `/send_join`, return it in the `/send_join` response in the `"event"` key
* Kick back joins with invalid authorising user IDs, use event from `"event"` key if returned in `RespSendJoin`
* Use invite helper in `QueryRestrictedJoinAllowed`
* Only use users with the power to invite, change error bubbling a bit
* Placate the almighty linter
One day I will nuke `gocyclo` from orbit and everything in the world will be much better for it.
* Review comments
Diffstat (limited to 'federationapi/internal')
-rw-r--r-- | federationapi/internal/perform.go | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/federationapi/internal/perform.go b/federationapi/internal/perform.go index c176a6ea..970a6465 100644 --- a/federationapi/internal/perform.go +++ b/federationapi/internal/perform.go @@ -210,10 +210,18 @@ func (r *FederationInternalAPI) performJoinUsingServer( } r.statistics.ForServer(serverName).Success() - authEvents := respSendJoin.AuthEvents.UntrustedEvents(respMakeJoin.RoomVersion) + // If the remote server returned an event in the "event" key of + // the send_join request then we should use that instead. It may + // contain signatures that we don't know about. + if respSendJoin.Event != nil && isWellFormedMembershipEvent( + respSendJoin.Event, roomID, userID, r.cfg.Matrix.ServerName, + ) { + event = respSendJoin.Event + } // Sanity-check the join response to ensure that it has a create // event, that the room version is known, etc. + authEvents := respSendJoin.AuthEvents.UntrustedEvents(respMakeJoin.RoomVersion) if err = sanityCheckAuthChain(authEvents); err != nil { return fmt.Errorf("sanityCheckAuthChain: %w", err) } @@ -271,6 +279,26 @@ func (r *FederationInternalAPI) performJoinUsingServer( return nil } +// isWellFormedMembershipEvent returns true if the event looks like a legitimate +// membership event. +func isWellFormedMembershipEvent(event *gomatrixserverlib.Event, roomID, userID string, origin gomatrixserverlib.ServerName) bool { + if membership, err := event.Membership(); err != nil { + return false + } else if membership != gomatrixserverlib.Join { + return false + } + if event.RoomID() != roomID { + return false + } + if event.Origin() != origin { + return false + } + if !event.StateKeyEquals(userID) { + return false + } + return true +} + // PerformOutboundPeekRequest implements api.FederationInternalAPI func (r *FederationInternalAPI) PerformOutboundPeek( ctx context.Context, |