Merge branch 'master' into add-nats-support

This commit is contained in:
Neil Alexander 2021-11-02 17:36:22 +00:00
commit 73d6964fb4
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
205 changed files with 5074 additions and 1217 deletions

View file

@ -30,7 +30,7 @@ import (
// AddPublicRoutes sets up and registers HTTP handlers on the base API muxes for the FederationAPI component.
func AddPublicRoutes(
fedRouter, keyRouter *mux.Router,
fedRouter, keyRouter, wellKnownRouter *mux.Router,
cfg *config.FederationAPI,
userAPI userapi.UserInternalAPI,
federation *gomatrixserverlib.FederationClient,
@ -43,7 +43,7 @@ func AddPublicRoutes(
servers federationAPI.ServersInRoomProvider,
) {
routing.Setup(
fedRouter, keyRouter, cfg, rsAPI,
fedRouter, keyRouter, wellKnownRouter, cfg, rsAPI,
eduAPI, federationSenderAPI, keyRing,
federation, userAPI, keyAPI, mscCfg,
servers,

View file

@ -30,7 +30,7 @@ func TestRoomsV3URLEscapeDoNot404(t *testing.T) {
fsAPI := base.FederationSenderHTTPClient()
// TODO: This is pretty fragile, as if anything calls anything on these nils this test will break.
// Unfortunately, it makes little sense to instantiate these dependencies when we just want to test routing.
federationapi.AddPublicRoutes(base.PublicFederationAPIMux, base.PublicKeyAPIMux, &cfg.FederationAPI, nil, nil, keyRing, nil, fsAPI, nil, nil, &cfg.MSCs, nil)
federationapi.AddPublicRoutes(base.PublicFederationAPIMux, base.PublicKeyAPIMux, base.PublicWellKnownAPIMux, &cfg.FederationAPI, nil, nil, keyRing, nil, fsAPI, nil, nil, &cfg.MSCs, nil)
baseURL, cancel := test.ListenAndServe(t, base.PublicFederationAPIMux, true)
defer cancel()
serverName := gomatrixserverlib.ServerName(strings.TrimPrefix(baseURL, "https://"))

View file

@ -37,12 +37,27 @@ func GetUserDevices(
return jsonerror.InternalServerError()
}
sigReq := &keyapi.QuerySignaturesRequest{
TargetIDs: map[string][]gomatrixserverlib.KeyID{
userID: {},
},
}
sigRes := &keyapi.QuerySignaturesResponse{}
keyAPI.QuerySignatures(req.Context(), sigReq, sigRes)
response := gomatrixserverlib.RespUserDevices{
UserID: userID,
StreamID: res.StreamID,
Devices: []gomatrixserverlib.RespUserDevice{},
}
if masterKey, ok := sigRes.MasterKeys[userID]; ok {
response.MasterKey = &masterKey
}
if selfSigningKey, ok := sigRes.SelfSigningKeys[userID]; ok {
response.SelfSigningKey = &selfSigningKey
}
for _, dev := range res.Devices {
var key gomatrixserverlib.RespUserDeviceKeys
err := json.Unmarshal(dev.DeviceKeys.KeyJSON, &key)
@ -56,6 +71,20 @@ func GetUserDevices(
DisplayName: dev.DisplayName,
Keys: key,
}
if targetUser, ok := sigRes.Signatures[userID]; ok {
if targetKey, ok := targetUser[gomatrixserverlib.KeyID(dev.DeviceID)]; ok {
for sourceUserID, forSourceUser := range targetKey {
for sourceKeyID, sourceKey := range forSourceUser {
if _, ok := device.Keys.Signatures[sourceUserID]; !ok {
device.Keys.Signatures[sourceUserID] = map[gomatrixserverlib.KeyID]gomatrixserverlib.Base64Bytes{}
}
device.Keys.Signatures[sourceUserID][sourceKeyID] = sourceKey
}
}
}
}
response.Devices = append(response.Devices, device)
}

View file

@ -40,22 +40,29 @@ func InviteV2(
) util.JSONResponse {
inviteReq := gomatrixserverlib.InviteV2Request{}
err := json.Unmarshal(request.Content(), &inviteReq)
switch err.(type) {
switch e := err.(type) {
case gomatrixserverlib.UnsupportedRoomVersionError:
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.UnsupportedRoomVersion(
fmt.Sprintf("Room version %q is not supported by this server.", e.Version),
),
}
case gomatrixserverlib.BadJSONError:
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.BadJSON(err.Error()),
}
case nil:
return processInvite(
httpReq.Context(), true, inviteReq.Event(), inviteReq.RoomVersion(), inviteReq.InviteRoomState(), roomID, eventID, cfg, rsAPI, keys,
)
default:
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.NotJSON("The request body could not be decoded into an invite request. " + err.Error()),
}
}
return processInvite(
httpReq.Context(), true, inviteReq.Event(), inviteReq.RoomVersion(), inviteReq.InviteRoomState(), roomID, eventID, cfg, rsAPI, keys,
)
}
// InviteV1 implements /_matrix/federation/v1/invite/{roomID}/{eventID}

View file

@ -71,8 +71,14 @@ func QueryDeviceKeys(
return util.JSONResponse{
Code: 200,
JSON: struct {
DeviceKeys interface{} `json:"device_keys"`
}{queryRes.DeviceKeys},
DeviceKeys interface{} `json:"device_keys"`
MasterKeys interface{} `json:"master_keys"`
SelfSigningKeys interface{} `json:"self_signing_keys"`
}{
queryRes.DeviceKeys,
queryRes.MasterKeys,
queryRes.SelfSigningKeys,
},
}
}

View file

@ -156,7 +156,9 @@ func fillInRooms(ctx context.Context, roomIDs []string, rsAPI roomserverAPI.Room
case topicTuple:
pub.Topic = contentVal
case canonicalTuple:
pub.CanonicalAlias = contentVal
if _, _, err := gomatrixserverlib.SplitID('#', contentVal); err == nil {
pub.CanonicalAlias = contentVal
}
case visibilityTuple:
pub.WorldReadable = contentVal == "world_readable"
// need both of these to determine whether guests can join

View file

@ -30,6 +30,7 @@ import (
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
"github.com/sirupsen/logrus"
)
// Setup registers HTTP handlers with the given ServeMux.
@ -41,7 +42,7 @@ import (
// applied:
// nolint: gocyclo
func Setup(
fedMux, keyMux *mux.Router,
fedMux, keyMux, wkMux *mux.Router,
cfg *config.FederationAPI,
rsAPI roomserverAPI.RoomserverInternalAPI,
eduAPI eduserverAPI.EDUServerInputAPI,
@ -85,6 +86,21 @@ func Setup(
return NotaryKeys(req, cfg, fsAPI, pkReq)
})
if cfg.Matrix.WellKnownServerName != "" {
logrus.Infof("Setting m.server as %s at /.well-known/matrix/server", cfg.Matrix.WellKnownServerName)
wkMux.Handle("/server", httputil.MakeExternalAPI("wellknown", func(req *http.Request) util.JSONResponse {
return util.JSONResponse{
Code: http.StatusOK,
JSON: struct {
ServerName string `json:"m.server"`
}{
ServerName: cfg.Matrix.WellKnownServerName,
},
}
}),
).Methods(http.MethodGet, http.MethodOptions)
}
// Ignore the {keyID} argument as we only have a single server key so we always
// return that key.
// Even if we had more than one server key, we would probably still ignore the
@ -449,7 +465,7 @@ func Setup(
httputil.MakeExternalAPI("federation_public_rooms", func(req *http.Request) util.JSONResponse {
return GetPostPublicRooms(req, rsAPI)
}),
).Methods(http.MethodGet)
).Methods(http.MethodGet, http.MethodPost)
v1fedmux.Handle("/user/keys/claim", httputil.MakeFedAPI(
"federation_keys_claim", cfg.Matrix.ServerName, keys, wakeup,

View file

@ -306,7 +306,7 @@ func (t *txnReq) processTransaction(ctx context.Context) (*gomatrixserverlib.Res
}
continue
}
if err = gomatrixserverlib.VerifyAllEventSignatures(ctx, []*gomatrixserverlib.Event{event}, t.keys); err != nil {
if err = event.VerifyEventSignatures(ctx, t.keys); err != nil {
util.GetLogger(ctx).WithError(err).Warnf("Transaction: Couldn't validate signature of event %q", event.EventID())
results[event.EventID()] = gomatrixserverlib.PDUResult{
Error: err.Error(),
@ -345,7 +345,7 @@ func (t *txnReq) processTransaction(ctx context.Context) (*gomatrixserverlib.Res
}
if c := len(results); c > 0 {
util.GetLogger(ctx).Infof("Processed %d PDUs from transaction %q", c, t.TransactionID)
util.GetLogger(ctx).Infof("Processed %d PDUs from %v in transaction %q", c, t.Origin, t.TransactionID)
}
return &gomatrixserverlib.RespSend{PDUs: results}, nil
}
@ -502,6 +502,22 @@ func (t *txnReq) processEDUs(ctx context.Context) {
}
}
}
case eduserverAPI.MSigningKeyUpdate:
var updatePayload eduserverAPI.CrossSigningKeyUpdate
if err := json.Unmarshal(e.Content, &updatePayload); err != nil {
util.GetLogger(ctx).WithError(err).WithFields(logrus.Fields{
"user_id": updatePayload.UserID,
}).Error("Failed to send signing key update to edu server")
continue
}
inputReq := &eduserverAPI.InputCrossSigningKeyUpdateRequest{
CrossSigningKeyUpdate: updatePayload,
}
inputRes := &eduserverAPI.InputCrossSigningKeyUpdateResponse{}
if err := t.eduAPI.InputCrossSigningKeyUpdate(ctx, inputReq, inputRes); err != nil {
util.GetLogger(ctx).WithError(err).Error("Failed to unmarshal cross-signing update")
continue
}
default:
util.GetLogger(ctx).WithField("type", e.Type).Debug("Unhandled EDU")
}
@ -695,7 +711,7 @@ withNextEvent:
}
if missing := len(missingAuthEvents); missing > 0 {
return fmt.Errorf("Event refers to %d auth_events which we failed to fetch", missing)
return fmt.Errorf("event refers to %d auth_events which we failed to fetch", missing)
}
return nil
}
@ -1342,7 +1358,7 @@ func (t *txnReq) lookupEvent(ctx context.Context, roomVersion gomatrixserverlib.
util.GetLogger(ctx).WithField("event_id", missingEventID).Warnf("Failed to get missing /event for event ID from %d server(s)", len(servers))
return nil, fmt.Errorf("wasn't able to find event via %d server(s)", len(servers))
}
if err := gomatrixserverlib.VerifyAllEventSignatures(ctx, []*gomatrixserverlib.Event{event}, t.keys); err != nil {
if err := event.VerifyEventSignatures(ctx, t.keys); err != nil {
util.GetLogger(ctx).WithError(err).Warnf("Transaction: Couldn't validate signature of event %q", event.EventID())
return nil, verifySigError{event.EventID(), err}
}

View file

@ -84,6 +84,14 @@ func (o *testEDUProducer) InputReceiptEvent(
return nil
}
func (o *testEDUProducer) InputCrossSigningKeyUpdate(
ctx context.Context,
request *eduAPI.InputCrossSigningKeyUpdateRequest,
response *eduAPI.InputCrossSigningKeyUpdateResponse,
) error {
return nil
}
type testRoomserverAPI struct {
api.RoomserverInternalAPITrace
inputRoomEvents []api.InputRoomEvent
@ -158,32 +166,6 @@ func (t *testRoomserverAPI) QueryEventsByID(
return nil
}
// Query the membership event for an user for a room.
func (t *testRoomserverAPI) QueryMembershipForUser(
ctx context.Context,
request *api.QueryMembershipForUserRequest,
response *api.QueryMembershipForUserResponse,
) error {
return fmt.Errorf("not implemented")
}
func (t *testRoomserverAPI) QueryPublishedRooms(
ctx context.Context,
request *api.QueryPublishedRoomsRequest,
response *api.QueryPublishedRoomsResponse,
) error {
return fmt.Errorf("not implemented")
}
// Query a list of membership events for a room
func (t *testRoomserverAPI) QueryMembershipsForRoom(
ctx context.Context,
request *api.QueryMembershipsForRoomRequest,
response *api.QueryMembershipsForRoomResponse,
) error {
return fmt.Errorf("not implemented")
}
// Query if a server is joined to a room
func (t *testRoomserverAPI) QueryServerJoinedToRoom(
ctx context.Context,
@ -195,53 +177,6 @@ func (t *testRoomserverAPI) QueryServerJoinedToRoom(
return nil
}
// Query whether a server is allowed to see an event
func (t *testRoomserverAPI) QueryServerAllowedToSeeEvent(
ctx context.Context,
request *api.QueryServerAllowedToSeeEventRequest,
response *api.QueryServerAllowedToSeeEventResponse,
) error {
return fmt.Errorf("not implemented")
}
// Query missing events for a room from roomserver
func (t *testRoomserverAPI) QueryMissingEvents(
ctx context.Context,
request *api.QueryMissingEventsRequest,
response *api.QueryMissingEventsResponse,
) error {
return fmt.Errorf("not implemented")
}
// Query to get state and auth chain for a (potentially hypothetical) event.
// Takes lists of PrevEventIDs and AuthEventsIDs and uses them to calculate
// the state and auth chain to return.
func (t *testRoomserverAPI) QueryStateAndAuthChain(
ctx context.Context,
request *api.QueryStateAndAuthChainRequest,
response *api.QueryStateAndAuthChainResponse,
) error {
return fmt.Errorf("not implemented")
}
// Query a given amount (or less) of events prior to a given set of events.
func (t *testRoomserverAPI) PerformBackfill(
ctx context.Context,
request *api.PerformBackfillRequest,
response *api.PerformBackfillResponse,
) error {
return fmt.Errorf("not implemented")
}
// Asks for the default room version as preferred by the server.
func (t *testRoomserverAPI) QueryRoomVersionCapabilities(
ctx context.Context,
request *api.QueryRoomVersionCapabilitiesRequest,
response *api.QueryRoomVersionCapabilitiesResponse,
) error {
return fmt.Errorf("not implemented")
}
// Asks for the room version for a given room.
func (t *testRoomserverAPI) QueryRoomVersionForRoom(
ctx context.Context,
@ -252,72 +187,10 @@ func (t *testRoomserverAPI) QueryRoomVersionForRoom(
return nil
}
// Set a room alias
func (t *testRoomserverAPI) SetRoomAlias(
ctx context.Context,
req *api.SetRoomAliasRequest,
response *api.SetRoomAliasResponse,
func (t *testRoomserverAPI) QueryServerBannedFromRoom(
ctx context.Context, req *api.QueryServerBannedFromRoomRequest, res *api.QueryServerBannedFromRoomResponse,
) error {
return fmt.Errorf("not implemented")
}
// Get the room ID for an alias
func (t *testRoomserverAPI) GetRoomIDForAlias(
ctx context.Context,
req *api.GetRoomIDForAliasRequest,
response *api.GetRoomIDForAliasResponse,
) error {
return fmt.Errorf("not implemented")
}
// Get all known aliases for a room ID
func (t *testRoomserverAPI) GetAliasesForRoomID(
ctx context.Context,
req *api.GetAliasesForRoomIDRequest,
response *api.GetAliasesForRoomIDResponse,
) error {
return fmt.Errorf("not implemented")
}
// Get the user ID of the creator of an alias
func (t *testRoomserverAPI) GetCreatorIDForAlias(
ctx context.Context,
req *api.GetCreatorIDForAliasRequest,
response *api.GetCreatorIDForAliasResponse,
) error {
return fmt.Errorf("not implemented")
}
// Remove a room alias
func (t *testRoomserverAPI) RemoveRoomAlias(
ctx context.Context,
req *api.RemoveRoomAliasRequest,
response *api.RemoveRoomAliasResponse,
) error {
return fmt.Errorf("not implemented")
}
func (t *testRoomserverAPI) QueryCurrentState(ctx context.Context, req *api.QueryCurrentStateRequest, res *api.QueryCurrentStateResponse) error {
return nil
}
func (t *testRoomserverAPI) QueryRoomsForUser(ctx context.Context, req *api.QueryRoomsForUserRequest, res *api.QueryRoomsForUserResponse) error {
return fmt.Errorf("not implemented")
}
func (t *testRoomserverAPI) QueryBulkStateContent(ctx context.Context, req *api.QueryBulkStateContentRequest, res *api.QueryBulkStateContentResponse) error {
return fmt.Errorf("not implemented")
}
func (t *testRoomserverAPI) QuerySharedUsers(ctx context.Context, req *api.QuerySharedUsersRequest, res *api.QuerySharedUsersResponse) error {
return fmt.Errorf("not implemented")
}
func (t *testRoomserverAPI) QueryKnownUsers(ctx context.Context, req *api.QueryKnownUsersRequest, res *api.QueryKnownUsersResponse) error {
return fmt.Errorf("not implemented")
}
func (t *testRoomserverAPI) QueryServerBannedFromRoom(ctx context.Context, req *api.QueryServerBannedFromRoomRequest, res *api.QueryServerBannedFromRoomResponse) error {
res.Banned = false
return nil
}