aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrendan Abolivier <contact@brendanabolivier.com>2017-09-11 19:08:24 +0100
committerMark Haines <mjark@negativecurvature.net>2017-09-11 19:08:24 +0100
commit28346b39e8e6d666442b00fed79a07e695046855 (patch)
tree4c564eae13f82969eedc82a0533fc78915c8326f
parent6cb9d900b9a8dceb87d8ecae2997b96ef3d07c8e (diff)
3PID invite exchange over federation (#222)
* Use federation to auth the event if the server isn't in the room * Use MakeAPI for 3pid onbind handler as it isn't a standard federation request * Error check * Temporarily disable tests * Fix return on 3PID invite * Re-enable tests * Remove useless else * gb vendor update github.com/matrix-org/gomatrixserverlib * gb vendor update github.com/matrix-org/gomatrixserverlib * Implement same behaviour as synapse * Fix condition and array initialisation * Log errors on iteration and throw one if no server could be reached * Fix err not being initialised * Fix lint * Fix import path
-rw-r--r--src/github.com/matrix-org/dendrite/federationapi/routing/routing.go7
-rw-r--r--src/github.com/matrix-org/dendrite/federationapi/writers/threepid.go46
2 files changed, 44 insertions, 9 deletions
diff --git a/src/github.com/matrix-org/dendrite/federationapi/routing/routing.go b/src/github.com/matrix-org/dendrite/federationapi/routing/routing.go
index 8d49800d..c67f8112 100644
--- a/src/github.com/matrix-org/dendrite/federationapi/routing/routing.go
+++ b/src/github.com/matrix-org/dendrite/federationapi/routing/routing.go
@@ -79,10 +79,9 @@ func Setup(
},
))
- v1fedmux.Handle("/3pid/onbind", common.MakeFedAPI(
- "3pid_onbind", cfg.Matrix.ServerName, keys,
- func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
- return writers.CreateInvitesFrom3PIDInvites(httpReq, query, cfg, producer)
+ v1fedmux.Handle("/3pid/onbind", common.MakeAPI("3pid_onbind",
+ func(req *http.Request) util.JSONResponse {
+ return writers.CreateInvitesFrom3PIDInvites(req, query, cfg, producer, federation)
},
))
diff --git a/src/github.com/matrix-org/dendrite/federationapi/writers/threepid.go b/src/github.com/matrix-org/dendrite/federationapi/writers/threepid.go
index ad9b4856..9fab040a 100644
--- a/src/github.com/matrix-org/dendrite/federationapi/writers/threepid.go
+++ b/src/github.com/matrix-org/dendrite/federationapi/writers/threepid.go
@@ -16,6 +16,7 @@ package writers
import (
"encoding/json"
+ "errors"
"fmt"
"net/http"
"time"
@@ -28,6 +29,8 @@ import (
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
+
+ "github.com/Sirupsen/logrus"
)
type invite struct {
@@ -48,7 +51,7 @@ type invites struct {
// CreateInvitesFrom3PIDInvites implements POST /_matrix/federation/v1/3pid/onbind
func CreateInvitesFrom3PIDInvites(
req *http.Request, queryAPI api.RoomserverQueryAPI, cfg config.Dendrite,
- producer *producers.RoomserverProducer,
+ producer *producers.RoomserverProducer, federation *gomatrixserverlib.FederationClient,
) util.JSONResponse {
var body invites
if reqErr := httputil.UnmarshalJSONRequest(req, &body); reqErr != nil {
@@ -57,7 +60,7 @@ func CreateInvitesFrom3PIDInvites(
evs := []gomatrixserverlib.Event{}
for _, inv := range body.Invites {
- event, err := createInviteFrom3PIDInvite(queryAPI, cfg, inv)
+ event, err := createInviteFrom3PIDInvite(queryAPI, cfg, inv, federation)
if err != nil {
return httputil.LogThenError(req, err)
}
@@ -83,6 +86,7 @@ func CreateInvitesFrom3PIDInvites(
// necessary data to do so.
func createInviteFrom3PIDInvite(
queryAPI api.RoomserverQueryAPI, cfg config.Dendrite, inv invite,
+ federation *gomatrixserverlib.FederationClient,
) (*gomatrixserverlib.Event, error) {
// Build the event
builder := &gomatrixserverlib.EventBuilder{
@@ -120,11 +124,11 @@ func createInviteFrom3PIDInvite(
}
if !queryRes.RoomExists {
- // TODO: Use federation to auth the event
- return nil, nil
+ // Use federation to auth the event
+ return nil, sendToRemoteServer(inv, federation, cfg, *builder)
}
- // Finish building the event
+ // Auth the event locally
builder.Depth = queryRes.Depth
builder.PrevEvents = queryRes.LatestEvents
@@ -154,6 +158,38 @@ func createInviteFrom3PIDInvite(
return &event, nil
}
+// sendToRemoteServer uses federation to send an invite provided by an identity
+// server to a remote server in case the current server isn't in the room the
+// invite is for.
+// Returns an error if it couldn't get the server names to reach or if all of
+// them responded with an error.
+func sendToRemoteServer(
+ inv invite, federation *gomatrixserverlib.FederationClient, cfg config.Dendrite,
+ builder gomatrixserverlib.EventBuilder,
+) (err error) {
+ remoteServers := make([]gomatrixserverlib.ServerName, 2)
+ _, remoteServers[0], err = gomatrixserverlib.SplitID('@', inv.Sender)
+ if err != nil {
+ return
+ }
+ // Fallback to the room's server if the sender's domain is the same as
+ // the current server's
+ _, remoteServers[1], err = gomatrixserverlib.SplitID('!', inv.RoomID)
+ if err != nil {
+ return
+ }
+
+ for _, server := range remoteServers {
+ err = federation.ExchangeThirdPartyInvite(server, builder)
+ if err == nil {
+ return
+ }
+ logrus.WithError(err).Warn("failed to send 3PID invite via %s", server)
+ }
+
+ return errors.New("failed to send 3PID invite via any server")
+}
+
// fillDisplayName looks in a list of auth events for a m.room.third_party_invite
// event with the state key matching a given m.room.member event's content's token.
// If such an event is found, fills the "display_name" attribute of the