mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-26 00:03:09 -06:00
Add relationship_room_id|servers to the unsigned section of events
This commit is contained in:
parent
435dbf2bde
commit
f33e2258f6
|
|
@ -48,6 +48,7 @@ type FederationSenderInternalAPI interface {
|
||||||
// Query the server names of the joined hosts in a room.
|
// Query the server names of the joined hosts in a room.
|
||||||
// Unlike QueryJoinedHostsInRoom, this function returns a de-duplicated slice
|
// Unlike QueryJoinedHostsInRoom, this function returns a de-duplicated slice
|
||||||
// containing only the server names (without information for membership events).
|
// containing only the server names (without information for membership events).
|
||||||
|
// The response will include this server if they are joined to the room.
|
||||||
QueryJoinedHostServerNamesInRoom(
|
QueryJoinedHostServerNamesInRoom(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *QueryJoinedHostServerNamesInRoomRequest,
|
request *QueryJoinedHostServerNamesInRoomRequest,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/federationsender/api"
|
"github.com/matrix-org/dendrite/federationsender/api"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// QueryJoinedHostServerNamesInRoom implements api.FederationSenderInternalAPI
|
// QueryJoinedHostServerNamesInRoom implements api.FederationSenderInternalAPI
|
||||||
|
|
@ -13,17 +12,11 @@ func (f *FederationSenderInternalAPI) QueryJoinedHostServerNamesInRoom(
|
||||||
request *api.QueryJoinedHostServerNamesInRoomRequest,
|
request *api.QueryJoinedHostServerNamesInRoomRequest,
|
||||||
response *api.QueryJoinedHostServerNamesInRoomResponse,
|
response *api.QueryJoinedHostServerNamesInRoomResponse,
|
||||||
) (err error) {
|
) (err error) {
|
||||||
joinedHosts, err := f.db.GetJoinedHosts(ctx, request.RoomID)
|
joinedHosts, err := f.db.GetJoinedHostsForRooms(ctx, []string{request.RoomID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
response.ServerNames = joinedHosts
|
||||||
response.ServerNames = make([]gomatrixserverlib.ServerName, 0, len(joinedHosts))
|
|
||||||
for _, host := range joinedHosts {
|
|
||||||
response.ServerNames = append(response.ServerNames, host.ServerName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: remove duplicates?
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,15 @@ const (
|
||||||
// Usage:
|
// Usage:
|
||||||
// hooks.Attach(hooks.KindNewEvent, func(headeredEvent interface{}) { ... })
|
// hooks.Attach(hooks.KindNewEvent, func(headeredEvent interface{}) { ... })
|
||||||
KindNewEvent = "new_event"
|
KindNewEvent = "new_event"
|
||||||
|
// KindModifyNewEvent is a hook which is called with *gomatrixserverlib.HeaderedEvent
|
||||||
|
// It is run before a new event is processed by the roomserver. This hook can be used
|
||||||
|
// to modify the event before it is persisted by adding data to `unsigned`.
|
||||||
|
// Usage:
|
||||||
|
// hooks.Attach(hooks.KindModifyNewEvent, func(headeredEvent interface{}) {
|
||||||
|
// ev := headeredEvent.(*gomatrixserverlib.HeaderedEvent)
|
||||||
|
// _ = ev.SetUnsignedField("key", "val")
|
||||||
|
// })
|
||||||
|
KindModifyNewEvent = "modify_new_event"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
|
fs "github.com/matrix-org/dendrite/federationsender/api"
|
||||||
"github.com/matrix-org/dendrite/internal/hooks"
|
"github.com/matrix-org/dendrite/internal/hooks"
|
||||||
"github.com/matrix-org/dendrite/internal/httputil"
|
"github.com/matrix-org/dendrite/internal/httputil"
|
||||||
"github.com/matrix-org/dendrite/internal/setup"
|
"github.com/matrix-org/dendrite/internal/setup"
|
||||||
|
|
@ -31,7 +32,11 @@ import (
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const constRelType = "m.reference"
|
const (
|
||||||
|
constRelType = "m.reference"
|
||||||
|
constRoomIDKey = "relationship_room_id"
|
||||||
|
constRoomServers = "relationship_servers"
|
||||||
|
)
|
||||||
|
|
||||||
type EventRelationshipRequest struct {
|
type EventRelationshipRequest struct {
|
||||||
EventID string `json:"event_id"`
|
EventID string `json:"event_id"`
|
||||||
|
|
@ -83,7 +88,7 @@ type EventRelationshipResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable this MSC
|
// Enable this MSC
|
||||||
func Enable(base *setup.BaseDendrite, rsAPI roomserver.RoomserverInternalAPI, userAPI userapi.UserInternalAPI) error {
|
func Enable(base *setup.BaseDendrite, rsAPI roomserver.RoomserverInternalAPI, fsAPI fs.FederationSenderInternalAPI, userAPI userapi.UserInternalAPI) error {
|
||||||
db, err := NewDatabase(&base.Cfg.MSCs.Database)
|
db, err := NewDatabase(&base.Cfg.MSCs.Database)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Cannot enable MSC2836: %w", err)
|
return fmt.Errorf("Cannot enable MSC2836: %w", err)
|
||||||
|
|
@ -98,6 +103,55 @@ func Enable(base *setup.BaseDendrite, rsAPI roomserver.RoomserverInternalAPI, us
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
hooks.Attach(hooks.KindModifyNewEvent, func(headeredEvent interface{}) {
|
||||||
|
he := headeredEvent.(*gomatrixserverlib.HeaderedEvent)
|
||||||
|
ctx := context.Background()
|
||||||
|
// we only inject metadata for events our server sends
|
||||||
|
userID := he.Sender()
|
||||||
|
_, domain, err := gomatrixserverlib.SplitID('@', userID)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if domain != base.Cfg.Global.ServerName {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// if this event has an m.relationship, add on the room_id and servers to unsigned
|
||||||
|
parent, child, relType := parentChildEventIDs(he)
|
||||||
|
if parent == "" || child == "" || relType == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
event, joinedToRoom := getEventIfVisible(ctx, rsAPI, parent, userID)
|
||||||
|
if !joinedToRoom {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = he.SetUnsignedField(constRoomIDKey, event.RoomID())
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(context.Background()).WithError(err).Warn("Failed to SetUnsignedField")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var servers []gomatrixserverlib.ServerName
|
||||||
|
if fsAPI != nil {
|
||||||
|
var res fs.QueryJoinedHostServerNamesInRoomResponse
|
||||||
|
err = fsAPI.QueryJoinedHostServerNamesInRoom(ctx, &fs.QueryJoinedHostServerNamesInRoomRequest{
|
||||||
|
RoomID: event.RoomID(),
|
||||||
|
}, &res)
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(context.Background()).WithError(err).Warn("Failed to QueryJoinedHostServerNamesInRoom")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
servers = res.ServerNames
|
||||||
|
} else {
|
||||||
|
servers = []gomatrixserverlib.ServerName{
|
||||||
|
base.Cfg.Global.ServerName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = he.SetUnsignedField(constRoomServers, servers)
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(context.Background()).WithError(err).Warn("Failed to SetUnsignedField")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
base.PublicClientAPIMux.Handle("/unstable/event_relationships",
|
base.PublicClientAPIMux.Handle("/unstable/event_relationships",
|
||||||
httputil.MakeAuthAPI("eventRelationships", userAPI, eventRelationshipHandler(db, rsAPI)),
|
httputil.MakeAuthAPI("eventRelationships", userAPI, eventRelationshipHandler(db, rsAPI)),
|
||||||
|
|
@ -264,34 +318,12 @@ func walkThread(
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *reqCtx) getEventIfVisible(eventID string) *gomatrixserverlib.HeaderedEvent {
|
func (rc *reqCtx) getEventIfVisible(eventID string) *gomatrixserverlib.HeaderedEvent {
|
||||||
var queryEventsRes roomserver.QueryEventsByIDResponse
|
event, joinedToRoom := getEventIfVisible(rc.ctx, rc.rsAPI, eventID, rc.userID)
|
||||||
err := rc.rsAPI.QueryEventsByID(rc.ctx, &roomserver.QueryEventsByIDRequest{
|
if event == nil {
|
||||||
EventIDs: []string{eventID},
|
|
||||||
}, &queryEventsRes)
|
|
||||||
if err != nil {
|
|
||||||
util.GetLogger(rc.ctx).WithError(err).Error("getEventIfVisible: failed to QueryEventsByID")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if len(queryEventsRes.Events) == 0 {
|
if joinedToRoom {
|
||||||
util.GetLogger(rc.ctx).Infof("event does not exist")
|
return event
|
||||||
return nil // event does not exist
|
|
||||||
}
|
|
||||||
event := queryEventsRes.Events[0]
|
|
||||||
|
|
||||||
// Allow events if the member is in the room
|
|
||||||
// TODO: This does not honour history_visibility
|
|
||||||
// TODO: This does not honour m.room.create content
|
|
||||||
var queryMembershipRes roomserver.QueryMembershipForUserResponse
|
|
||||||
err = rc.rsAPI.QueryMembershipForUser(rc.ctx, &roomserver.QueryMembershipForUserRequest{
|
|
||||||
RoomID: event.RoomID(),
|
|
||||||
UserID: rc.userID,
|
|
||||||
}, &queryMembershipRes)
|
|
||||||
if err != nil {
|
|
||||||
util.GetLogger(rc.ctx).WithError(err).Error("getEventIfVisible: failed to QueryMembershipForUser")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if queryMembershipRes.IsInRoom {
|
|
||||||
return &event
|
|
||||||
}
|
}
|
||||||
if rc.req.AutoJoin {
|
if rc.req.AutoJoin {
|
||||||
var joinRes roomserver.PerformJoinResponse
|
var joinRes roomserver.PerformJoinResponse
|
||||||
|
|
@ -305,12 +337,42 @@ func (rc *reqCtx) getEventIfVisible(eventID string) *gomatrixserverlib.HeaderedE
|
||||||
util.GetLogger(rc.ctx).WithError(joinRes.Error).WithField("room_id", event.RoomID()).Error("Failed to auto-join room")
|
util.GetLogger(rc.ctx).WithError(joinRes.Error).WithField("room_id", event.RoomID()).Error("Failed to auto-join room")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &event
|
return event
|
||||||
}
|
}
|
||||||
util.GetLogger(rc.ctx).Infof("user not in room and auto_join disabled")
|
util.GetLogger(rc.ctx).Infof("user not in room and auto_join disabled")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getEventIfVisible(ctx context.Context, rsAPI roomserver.RoomserverInternalAPI, eventID, userID string) (*gomatrixserverlib.HeaderedEvent, bool) {
|
||||||
|
var queryEventsRes roomserver.QueryEventsByIDResponse
|
||||||
|
err := rsAPI.QueryEventsByID(ctx, &roomserver.QueryEventsByIDRequest{
|
||||||
|
EventIDs: []string{eventID},
|
||||||
|
}, &queryEventsRes)
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(ctx).WithError(err).Error("getEventIfVisible: failed to QueryEventsByID")
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
if len(queryEventsRes.Events) == 0 {
|
||||||
|
util.GetLogger(ctx).Infof("event does not exist")
|
||||||
|
return nil, false // event does not exist
|
||||||
|
}
|
||||||
|
event := queryEventsRes.Events[0]
|
||||||
|
|
||||||
|
// Allow events if the member is in the room
|
||||||
|
// TODO: This does not honour history_visibility
|
||||||
|
// TODO: This does not honour m.room.create content
|
||||||
|
var queryMembershipRes roomserver.QueryMembershipForUserResponse
|
||||||
|
err = rsAPI.QueryMembershipForUser(ctx, &roomserver.QueryMembershipForUserRequest{
|
||||||
|
RoomID: event.RoomID(),
|
||||||
|
UserID: userID,
|
||||||
|
}, &queryMembershipRes)
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(ctx).WithError(err).Error("getEventIfVisible: failed to QueryMembershipForUser")
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return &event, queryMembershipRes.IsInRoom
|
||||||
|
}
|
||||||
|
|
||||||
type walkInfo struct {
|
type walkInfo struct {
|
||||||
eventInfo
|
eventInfo
|
||||||
SiblingNumber int
|
SiblingNumber int
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ func Enable(base *setup.BaseDendrite, monolith *setup.Monolith) error {
|
||||||
func EnableMSC(base *setup.BaseDendrite, monolith *setup.Monolith, msc string) error {
|
func EnableMSC(base *setup.BaseDendrite, monolith *setup.Monolith, msc string) error {
|
||||||
switch msc {
|
switch msc {
|
||||||
case "msc2836":
|
case "msc2836":
|
||||||
return msc2836.Enable(base, monolith.RoomserverAPI, monolith.UserAPI)
|
return msc2836.Enable(base, monolith.RoomserverAPI, monolith.FederationSenderAPI, monolith.UserAPI)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("EnableMSC: unknown msc '%s'", msc)
|
return fmt.Errorf("EnableMSC: unknown msc '%s'", msc)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ func (w *inputWorker) start() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case task := <-w.input:
|
case task := <-w.input:
|
||||||
|
hooks.Run(hooks.KindModifyNewEvent, &task.event.Event)
|
||||||
_, task.err = w.r.processRoomEvent(task.ctx, task.event)
|
_, task.err = w.r.processRoomEvent(task.ctx, task.event)
|
||||||
if task.err == nil {
|
if task.err == nil {
|
||||||
hooks.Run(hooks.KindNewEvent, &task.event.Event)
|
hooks.Run(hooks.KindNewEvent, &task.event.Event)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue