aboutsummaryrefslogtreecommitdiff
path: root/federationapi/internal
diff options
context:
space:
mode:
authorNeil Alexander <neilalexander@users.noreply.github.com>2022-05-25 10:05:30 +0100
committerGitHub <noreply@github.com>2022-05-25 10:05:30 +0100
commit81843e8836e6f8f334c7b5fd1433c427c10a9443 (patch)
treeda86bc862d46103b955431961df95fab90c199b6 /federationapi/internal
parentd621dd2986fa0b8cce9d164a7249456d0be47c81 (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.go30
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,